Deleted JPGRAPH. Each developer must have his own version due to problems with Win/Linux versions (raul)

git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@104 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
slerena 2006-07-06 17:16:40 +00:00
parent 36a4788d57
commit e5e7f96f5a
33 changed files with 0 additions and 27337 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
<?php
//=======================================================================
// File: IMGDATA_BEVELS.INC
// Description: Base64 encoded images for round bevels
// Created: 2003-03-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: imgdata_bevels.inc 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class ImgData_Bevels extends ImgData {
protected $name = 'Round Bevels';
protected $an = array(MARK_IMG_BEVEL => 'imgdata');
protected $colors = array('green','purple','orange','red','yellow');
protected $index = array('green'=>1,'purple'=>4,'orange'=>2,'red'=>0,'yellow'=>3);
protected $maxidx = 4 ;
protected $imgdata ;
function ImgData_Bevels() {
//==========================================================
// File: bullets_balls_red_013.png
//==========================================================
$this->imgdata[0][0]= 337 ;
$this->imgdata[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'.
'BMVEX////////27t/f3+LFwcmNxMuxm62DmqKth1VpZmIWg6fv'.
'HCa7K0BwMEytCjFnIyUlEBg9vhQvAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAxcBNhk+pYJVAAAAl0lEQVR4nE2Q2xLDIAgFHUWBKJf//9'.
'oekmbafVDZARRbK/pYTKP9WNcNv64zzUdd9BjmrgnsVXRNSzO3'.
'CJ5ahdhy0XKQkxld1kxb45j7dp0x2lBNOyVgQpMaoadX7Hs7zr'.
'P1yKj47DKBnKaBKiSAkNss7O6PkMx6kIgYXISQJpcZCqdY6KR+'.
'J1PkS5Xob/h7MNz8x6D3fz5DKQjpkZOBYAAAAABJRU5ErkJggg'.
'==' ;
//==========================================================
// File: bullets_balls_green_013.png
//==========================================================
$this->imgdata[1][0]= 344 ;
$this->imgdata[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'.
'BMVEX////////27t/e3+K3vriUub/Dm18j4xc3ob10k0ItqQlU'.
'e5JBmwpxY1ENaKBgUh0iHgwsSre9AAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAxcBNTfJXtxZAAAAnklEQVR4nE2QWY4EMQhDUVhSIRC4/2'.
'kbaqLp9p+f2AxAayAzDfiK9znPORuvH0x8Ss9z6I9sHp6tcxE9'.
'nLmWmebmt5F5p2AR0+C9AWpLBjXRaZsCAT3SqklVp0YkAWaGtd'.
'c5Z41/STYpPzW7BjyiRrwkVmQto/Cw9tNEMvsgcekyCyFPboIu'.
'IsuXiKffYB4NK4r/h6d4g9HPPwCR7i8+GscIiiaonUAAAAAASU'.
'VORK5CYII=' ;
//==========================================================
// File: bullets_balls_oy_035.png
//==========================================================
$this->imgdata[2][0]= 341 ;
$this->imgdata[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'.
'BMVEX////////27t/f3+K5tbqNwcjnkjXjbxR2i5anfEoNkbis'.
'PBxpU0sZbZejKgdqIRIlERIwYtkYAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAxcBNgK0wEu5AAAAm0lEQVR4nE3QVxIEIQgEUErAgTHA/U'.
'+7zbipf9RXgoGo0liMmX6RdSPLPtZM9F4LuuSIaZtZWffiU6Iz'.
'Y8SOMF0NogBj30ioGRGLZgiPvce1TbIRz6oBQEbOFGK0rIoxrn'.
'5hDomMA1cfGRCaRVhjS3gkzheM+4HtnlkXcvdZhWG4qZawewe6'.
'9Jnz/TKLB/ML6HUepn//QczazuwFO/0Ivpolhi4AAAAASUVORK'.
'5CYII=' ;
//==========================================================
// File: bullets_balls_oy_036.png
//==========================================================
$this->imgdata[3][0]= 340 ;
$this->imgdata[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'.
'BMVEX////////27t/e3+LO3hfYzz65ubiNwci6uQ12ipadgVGa'.
'fwsNkbhnVkcaZ5dwSA8lFg7CEepmAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElN'.
'RQfTAxcCBySi1nevAAAAjElEQVR4nFXPWw7EIAgFUNMoCMhj/6'.
'staKczc/2RkwjS2glQ+w3YytgXCXCZpRo8gJdGxZadJws13CUP'.
'4SZI4MYiUxypeiGGw1XShVBTNN9kLXP2GRrZPFvKgd7z/sqGGV'.
'7C7r7r3l09alYN3iA8Yn+ImdVrNoEeSRqJPAaHfhZzLYwXstdZ'.
'rP3n2bvdAI4INwtihiwAAAAASUVORK5CYII=' ;
//==========================================================
// File: bullets_balls_pp_019.png
//==========================================================
$this->imgdata[4][0]= 334 ;
$this->imgdata[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'.
'BMVEX////+/v7i4eO/w8eHxcvKroNVormtfkjrMN2BeXQrepPc'.
'Esy4IL+OFaR7F25LHF8mFRh5XXtUAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAxcBNgkjEpIxAAAAlElEQVR4nE2QAQ7FIAhDDTAVndL7n3'.
'ZV/7JfEwMvFIWUlkTMVNInbVv5ZeJqG7Smh2QTBwJBpsdizAZP'.
'5NyW0awhK8kYodnZxS6ECvPRp2sI+y7PBv1mN02KH7h77QCJ8D'.
'4VvY5NUgEmCwj6ZMzHtJRgRSXwC1gfcqJJH0GBnSnK1kUQ72DY'.
'CPBv+MCS/e0jib77eQAJxwiEWm7hFwAAAABJRU5ErkJggg==' ;
}
}
?>

View File

@ -1,178 +0,0 @@
<?php
//=======================================================================
// File: IMGDATA_DIAMONDS.INC
// Description: Base64 encoded images for diamonds
// Created: 2003-03-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: imgdata_diamonds.inc 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class ImgData_Diamonds extends ImgData {
protected $name = 'Diamonds';
protected $an = array(MARK_IMG_DIAMOND =>'imgdata');
protected $colors = array('lightblue','darkblue','gray',
'blue','pink','purple','red','yellow');
protected $index = array('lightblue' =>7,'darkblue'=>2,'gray'=>6,
'blue'=>4,'pink'=>1,'purple'=>5,'red'=>0,'yellow'=>3);
protected $maxidx = 7 ;
protected $imgdata ;
function ImgData_Diamonds() {
//==========================================================
// File: diam_red.png
//==========================================================
$this->imgdata[0][0]= 668 ;
$this->imgdata[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/F'.
'BMVEX///////+cAAD/AADOAABjAABrAADWGBjOCAj/CAj/GBj/'.
'EBCcCAiMOTl7KSl7ISFzGBilGBjOEBBrCAjv5+eMQkK1QkKtMT'.
'GtKSnWKSn/KSlzEBCcEBDexsb/tbXOe3ucWlqcUlKUSkr/e3vn'.
'a2u9UlL/a2uEMTHeUlLeSkqtOTn/UlL/SkrWOTn/QkL/OTmlIS'.
'H/MTH/ISH39/f/9/f35+fezs7/5+fvzs7WtbXOra3nvb3/zs7G'.
'nJzvtbXGlJTepaW9jIy1hITWlJS1e3uta2ulY2P/lJTnhITne3'.
'vGY2O9Wlr/c3PeY2O1Skr/Y2P/WlreQkLWISGlEBCglEUaAAAA'.
'AXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAA'.
'sSAdLdfvwAAAAHdElNRQfTAwsWEw5WI4qnAAABGUlEQVR4nHXQ'.
'1XLDMBAFUKUCM1NiO8zcpIxpp8z0//9SWY7b2LHv6EU6s1qtAN'.
'iMBAojLPkigpJvogKC4pxDuQipjanlICXof1RQDkYEF21mKIfg'.
'/GGKtjAmOKt9oSyuCU7OhyiDCQnjowGfRnooCJIkiWJvv8NxnG'.
'nyNAwFcekvZpPP3mu7Vrp8fOq8DYbTyjdnAvBj7Jbd7nP95urs'.
'+MC2D6unF+Cu0VJULQBAlsOQuueN3Hrp2nGUvqppemBZ0aU7Se'.
'SXvYZFMKaLJn7MH3btJmZEMEmGSOreqy0SI/4ffo3uiUOYEACy'.
'OFopmNWlP5uZd9uPWmUoxvK9ilO9NtBo6mS7KkZD0fOJYqgGBU'.
'S/T7OKCAA9tfsFOicXcbxt29cAAAAASUVORK5CYII=' ;
//==========================================================
// File: diam_pink.png
//==========================================================
$this->imgdata[1][0]= 262 ;
$this->imgdata[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'.
'BMVEX///+AgID/M5n/Zpn/zMz/mZn1xELhAAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'.
'AHdElNRQfTAwsWEi3tX8qUAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'.
'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'.
'6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'.
'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'.
'==' ;
//==========================================================
// File: diam_blue.png
//==========================================================
$this->imgdata[2][0]= 662 ;
$this->imgdata[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA+V'.
'BMVEX///+AgIAAAJwAAP8AAM4AAGMAAGsQEP8YGHMQEHMYGP8Q'.
'EKUICJwICM5KSpQxMYQpKXsYGNYQEM4ICGsICP97e85aWpw5OY'.
'xSUv85ObVCQt4xMa0pKa0hIaUpKf+9vd6EhLVra+dzc/9SUr1r'.
'a/9aWt5SUt5CQrVaWv9KSv8hIXs5Of8xMf8pKdYhIdYYGKUhIf'.
'/Ozs739//v7/fn5+/v7//n5/fW1ufOzufOzu/W1v+trc69veel'.
'pc6trd6UlMa9vf+MjL21tfe1tf+UlNZzc61ra6Wlpf+EhOeMjP'.
'9ra8ZSUpyEhP9CQoxKSrVCQv85Od4xMdYQENZnJhlWAAAAAXRS'.
'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'.
'LdfvwAAAAHdElNRQfTAwsWEx3Snct5AAABFklEQVR4nHXR5XbD'.
'IBgGYM6AuHsaqbvOfeuknev9X8xISbplSd5/8JyXwwcA/I0AKm'.
'PFchVBdvKNKggKQx2VIoRwMZihMiQE49YUlWBCcPL0hYq4ITh+'.
'qKECUoLDZWqoQNA766F/mJHlHXblPJJNiyURhM5eU9cNw5BlmS'.
'IrLOLxhzfotF7vwO2j3ez2ap/TmW4AIM7DoN9+tu+vLk6Pdg9O'.
'6ufXjfXLm6pxPACSJIpRFAa+/26DhuK6qjbiON40k0N3skjOvm'.
'NijBmchF5mi+1jhQqDmWyIzPp1hUlrv8On5l+6mMm1tigFNyrt'.
'5R97g+FKKyGKkTNKesXPJTZXOFIrUoKiypcTQVHjK4g8H2dWEQ'.
'B8bvUDLSQXSr41rmEAAAAASUVORK5CYII=' ;
//==========================================================
// File: diam_yellow.png
//==========================================================
$this->imgdata[3][0]= 262 ;
$this->imgdata[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'.
'BMVEX///+AgIBmMwCZZgD/zADMmQD/QLMZAAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'.
'AHdElNRQfTAwsWEwcv/zIDAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'.
'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'.
'6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'.
'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'.
'==' ;
//==========================================================
// File: diam_lightblue.png
//==========================================================
$this->imgdata[4][0]= 671 ;
$this->imgdata[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/1'.
'BMVEX///+AgIAAnP8A//8Azv8AY/8Aa/8I//8Y1v8Izv8Y//8Q'.
'//8InP8Qzv8Ypf85jP8he/8Yc/8Ia/8pe/8p//8p1v9Ctf8xrf'.
'8prf8QnP8Qc/9CjP+1//97//9r//9S//9K//9C//85//8x//8h'.
'//9r5/9K3v9S3v851v97zv9Svf85rf8hpf/G3v9SnP9anP9KlP'.
'8xhP/n7//v7+f3///n///O//+U//9z//9j//9a//975/9C3v8h'.
'1v+E5/+17/9j3v/O7//n9/+95/+l3v9jxv+U1v8Qpf9avf9Ktf'.
'+Uxv+11v97tf9rrf+cxv+Mvf9jpf+tzv+Etf/O3v/39/8Akkxr'.
'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'.
'IAAAsSAdLdfvwAAAAHdElNRQfTAwsWEiHk6Ya/AAABGUlEQVR4'.
'nHXQ13KDMBAF0J2o0E01GHDvJa7p3em95/+/JQJMYjDc0Yt0Zr'.
'VaAaxHgtxwbSGPkGQpOIeQ2ORxJiJmNWYZyAhZR0WcgQGhViU0'.
'nEGoedDHGxgRapRPcRpXhOr7XZzCmLjaXk9IIjvkOEmSRLG62+'.
'F5XlEElhA5sW21GvXj6mGlDBfnJ51lr9svnvEKwH1hu2QPbwd3'.
'N9eXVzuL7/Hn29frdKaamgcgy67L3HFG9gDefV+dm5qme4YRXL'.
'oVR374mRqUELZYosf84XAxISFRQuMh4rrH8YxGSP6HX6H97NNQ'.
'KEAaR08qCeuSnx2a8zIPWqUowtKHSRK91rAw0elmVYQFVc8mhq'.
'7p5RD7Ps3IIwA9sfsFxFUX6eZ4Zh4AAAAASUVORK5CYII=' ;
//==========================================================
// File: diam_purple.png
//==========================================================
$this->imgdata[5][0]= 657 ;
$this->imgdata[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/F'.
'BMVEX///////8xAP/OAP+cAP9jAP9rAP+cCP85CP/OEP9SKf/O'.
'CP9CEP9zGP9rCP+lGP/WOf/WIf9KIf9jOf+MQv+EMf97If9zEP'.
'+1Sv+lIf/ne//eUv/na//n5//Oxv/Wzv+chP9zUv97Wv9rQv9a'.
'Mf9KGP/v5/+te/97Kf+9Y/+tOf+tKf+lEP/vtf/WMf/WKf/v7+'.
'f39/+tnP+9rf9rSv9jQv9CGP+ljP+EY//Gtf+tlP+Ma/9zSv/e'.
'zv+UUv+9lP+cWv+lY/+cUv+MOf+EKf+UQv/Opf/OhP/Ga/+1Qv'.
'/Oe/+9Uv/ntf/eWv/eSv/WGP/3zv/vlP/WEP//9/+pL4oHAAAA'.
'AXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAA'.
'sSAdLdfvwAAAAHdElNRQfTAwsWEjX+M1LCAAABDklEQVR4nHXQ'.
'1bLDIBAGYFqIEW+ksbr7cXd3ff93OUCamdOE/Mxw882yywLwPz'.
'+gNKotlRFUVnNUQlCxTMRFCKEdE+MgpJaEiIOU4DKaoSIygtb3'.
'FBUQrm3xjPK4JvXjK0A5hFniYSBtIilQVYUm+X0KTVNiYah+2q'.
'ulFb8nUbSovD2+TCavwXQWmnMA6ro+di+uR5cPzfPhVqPV3N1p'.
'n3b3+rimAWAYhP3xnXd7P6oc9vadPsa1wYEs00dFQRAFehlX21'.
'25Sg9NOgwF5jeNTjVL9om0TjDc1lmeCKZ17nFPzhPtSRt6J06R'.
'WKUoeG3MoXRa/wjLHGLodwZcotPqjsYngnWslRBZH91hWTbpD2'.
'EdF1ECWW1SAAAAAElFTkSuQmCC' ;
//==========================================================
// File: diam_gray.png
//==========================================================
$this->imgdata[6][0]= 262 ;
$this->imgdata[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'.
'BMVEX//////wAzMzNmZmbMzMyZmZlq4Qo5AAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'.
'AHdElNRQfTAwsWExZFTxLxAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'.
'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'.
'6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'.
'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'.
'==' ;
//==========================================================
// File: diam_blgr.png
//==========================================================
$this->imgdata[7][0]= 262 ;
$this->imgdata[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'.
'BMVEX///+AgIBmzP9m///M//+Z//8hMmBVAAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'.
'AHdElNRQfTAwsWEwCxm6egAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'.
'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'.
'6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'.
'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'.
'==' ;
}
}
?>

View File

@ -1,518 +0,0 @@
<?php
//=======================================================================
// File: IMGDATA_PUSHPINS.INC
// Description: Base64 encoded images for pushpins
// Created: 2003-03-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: imgdata_pushpins.inc 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class ImgData_PushPins extends ImgData {
protected $name = 'Push pins';
protected $an = array(MARK_IMG_PUSHPIN => 'imgdata_small',
MARK_IMG_SPUSHPIN => 'imgdata_small',
MARK_IMG_LPUSHPIN => 'imgdata_large');
protected $colors = array('blue','green','orange','pink','red');
protected $index = array('red' => 0, 'orange' => 1, 'pink' => 2, 'blue' => 3, 'green' => 4 ) ;
protected $maxidx = 4 ;
protected $imgdata_large, $imgdata_small ;
function ImgData_PushPins() {
// The anchor should be where the needle "hits" the paper
// (bottom left corner)
$this->anchor_x = 0;
$this->anchor_y = 1;
//==========================================================
// File: ppl_red.png
//==========================================================
$this->imgdata_large[0][0]= 2490 ;
$this->imgdata_large[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMKBh4Ryh89CgAACUdJREFUeJy9mNtTFFcexz+/7p'.
'4Lw1wZJKDGCAwmDAqUySamcCq1ed6k9mn3UfMP7F+1T3nYqn2J'.
'lZdoDEjpbq0KG8EBFBFBEJye6Zmenkv32Ydu5GYiUMmeqq6uqT'.
'6Xz3zP73aOcIKmAQkIFyD3N/jrBPwlKjLQEglVlJKyUjR3u7cc'.
'WLoP3/4dvv03LNrQ8I6x1rFbDML9kOmHvh7IRHU9JKmUSG8vpF'.
'IoXX/TV0AiEM5A5jT0noFMFMJHXUt/d5f9TUAbhtQ3cPFruDog'.
'8klHMnmO0dGYe/myOJGINEwTz3F2higFXgy8PpAkOC+h8hoaCt'.
'4ppHFcQAWSgOQlyI/p+lUjmRxWAwNJd3xca/f34yoFi4tgmjtD'.
'NIFkJ4xcgBCgVqEBFJ9DqcZea/gNAAVEg7AOGYnHe9XoaJd3+X'.
'LISSSwnz6lsbKCZ9sHh4UVdBkwdA6cPwNnIfJPmC3Ctgft3wwQ'.
'QPkvTZJJnbExzfvsM2nMzVG7e5fG48d4lnXwTwEYCjJxuHQBog'.
'BHUfKkgAIIhiGk06hTp/Dm5qS1uYlXLvtWd4gPgIiCrAEcVckT'.
'Ab5p7TaYJrK1hQaEenrwSiVfQdc91P0kSp7Ii89D5ksY/kAkLy'.
'IZXFdXkQjS1YUSEbdcRu168V6+HTUNIKJDRwdE+sBIQmP9Ld59'.
'bEBA3of4F/D+uXb7rGaaCSmXI3pPj64PDaHCYfEqFVSjgWo2D2'.
'73XlJNQTgCyQykIuBWoNKEeh1aLXBPBCggGdBOgxZVSjoajVhH'.
'o5HWlIpq4bCQSgm9vXhK4ZZKh5SUYygp4J1EQVUD9xlU18BJQD'.
'bUbJ5T5XJStyxN9fSI099P3baxV1dRloW2h2ivx/yakg2ot6F1'.
'EkCa4G1D+zVEq5ArKTWM42Q6HUczQV7U66w9e0ZpdRXlOIQ5vF'.
'VHUXILKify4jiEzkOqC3peQMoBQymFlMt4Dx6wUSxSsm2UZXEK'.
'P30QvOUt8/2Sd78CdWwFDTA+gsw3cOlPcPUD+CQB52oQ21RKXM'.
'eRhGXhOg7VoKrx8KuS4ygZhVg3ZI8FGIfwR9BVgAtfwxdXdP3L'.
'86nUR91dXelNXTeWWy10paQHX602YAP1ADASAL7LJvFtMpOCc0'.
'cG3FHuGlz6Gr4YEpnoTCbzsdHRbOzy5RCRiLRMk5rjyOtAimwA'.
'U4U3SurBN/0wnAASBCVDIKpB4kiAB5Ub0/UvO9LpPAMDGfn005'.
'AxPCzxep3Q6iqPLUseBoufCZRsAE6g5g5kKIDfKUj3wnpAG8QB'.
'/Z1OIqANQuI65AtwNScyYXR2XlAXL2YZHzcklRKWl5GVFXFtGx'.
'MoAiV/EQaAGH6BUQNWgQpwFngv+Ca8KUAQEBcwgTJHyMV7679R'.
'XS8YqdSI6u/PMD5ukMtJY3GR2uQkr5aXeWVZOEALmA8WsIAxfL'.
'd0goVLAdCOd+/YpgqeVtBv4yiA++q/RKKXixe7GB8PSyoljcVF'.
'yg8fyubyMpulEk2lyAIfAAvAC+B+oOQFoAt/+0rAejB/EzjNri'.
'vvqNnCd64jxcE39V8spnP+vMbAgDSePKE2NcXm06dslMuUlcID'.
'TuFvqwXMBU8N39bGgRR+ki0Dz4L5DSAe9NGD7zq+6kcN1L6H2b'.
'ao5WWaQHllRTafPmWrVMJUimoAQrBYJFjQwre7B6A8YAi8LCgD'.
'5DVo6/hbb/iHK1KggvFeD3hHziQKEMuiNTNDbXGRTdtmw7Iwla'.
'KGH0oqwbscLOoG46rAY6AOzRhY74PT6QuUKEN4PegXxd/yEDTT'.
'YMWOk+oEaLkuFdNk0zTZwjfkavDUArXWgGXgFb4dEShXhfYqlI'.
'ow3w9rg3B6ED60IOOA5oEYQBrcpG+mj9bg0VG8GMJhVDZLyzAo'.
'VSq8rFYxXXefcjVgG9+uisDrXUCApoKSBcUHMBmHhfcgNwhtD3'.
'q9IG6Lr15b4OUTmPwBJt8JqGuapp05o0mhoHnptLQfPsR+8IBK'.
'uYyNH3yr+B77LHheA3tK1Ta+IrMeTL2C6Xl48TOsNWDDgAz7s5'.
'/r+krP/eddCsbj8fDQ4GBm9MqVvvRXX2VULBayRGRzaYn1SoWa'.
'UjgB4PIB5QK4ZgBXBKaAHxQsrED1H7CRgCUPwgHZDqACmhWwXv'.
'2aDRqGYeRyufS169cvThQKV88PDuYbW1vJ5VRK+5euqxWlPMdX'.
'SRqgreHbZGN3ijfKBXBTAeh2Fdwi2MofshP/dvKwCmKhp4m83Y'.
'vj8Xg4l8tlCoXC0MTExMTFkZE/1m37wvLGRvKRacoD1209E7Fc'.
'pZwYREOQqEJ4z3HskHLsz4AoXykPIBSN0t3dTTQafROoHdumXC'.
'4fjoMiog0ODiauX7+eLxQKV3O53ETdti88nJnJ3rl505ifmWm3'.
'arWSodR8GNbycDoNHy5C5jFold1k8d+DyvELNwg93d18/vnn9P'.
'X1oes6nufx/Plz7t+/fxhQKSWJRCI5NjaWHxkZKdj1+sjSwkJm'.
'+uZN/dZ337VqCwullGUVdZjsgIUC5LqhrUPvCugWuApeApPAzY'.
'PKHWyaphGNRunt7WVwcBARwfM8Ojo6sCzrMKBhGLphGFEF2Wq1'.
'2jc7M5OZ/vHH0MPbt93awkJJmeZsC6ZaMK3DCwvWdNioQUb5B6'.
'AdBR+9SzkAz/NwHIeXL18iIui6TjgcJplMMjY2th8wHo+Hh4aG'.
'MsPDw6fddru7+Phxx51bt/RbN260qwsLpZhlFZsw9QJ+2Pbrga'.
'oJG2FY2oKwuTtVEz9uV34NbqdtbW0xPT1NNBoF4MyZM1y5coWu'.
'rq5dQBHRcrlc4tq1a/l8Pj9RMs38ndu3Ez//9JNXLRZNyuXZJk'.
'xVYKoExQpsK/+IaAuYb7no8zjC/R+A4zisrq7u+53NZjl16tQ+'.
'QIlEIslsNpuPRCJXZ2dnh2/duNFRW1oy07a96MKd575yxRqU1B'.
'5vPMpF5HHa1tYW9+7do7Ozc/eQpZTSQ6FQt1Lq8pMnT/5w7969'.
'nuLcXE1rNufO9fRMhlKpOyvt9qPtVmvb25fFfvvWbrepVCqHwo'.
'xaX19vff/996ZhGC8qlkW9Wt1Onz073fXxxz+6MB+9e9dUjuO+'.
'7ebq9wLdB9hoNCrr6+s/4wf3FCJW3fPmTZhXsNWCprjuW66Dfr'.
'928KAfBhJAEgiJSLuzs7OSTqctoFkqlZRt26j/I+L/AGjPTN4d'.
'Nqn4AAAAAElFTkSuQmCC' ;
//==========================================================
// File: ppl_orange.png
//==========================================================
$this->imgdata_large[1][0]= 2753 ;
$this->imgdata_large[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFQ0VCkHCzQAACk5JREFUeJytmGtzG0d2hp8zNw'.
'AEcRdJ6EJK9FL0CqZUm9jWbkwq3vhDstl8dmLvz8rP2H8Q75ZT'.
'pkRfpLgqsS6WIFEKGYkiSBCDO+banQ8DUpRWEkklXQUUqlCDfv'.
'rp857pgfAOQ4AMOJdg4R/hX96Hf06bvDc5iT07i8yeg8ksiIAI'.
'4TBi/ds9/vivD/njapNHvRBfHXMu410AM+BUoVSF05NQsi1sO4'.
'8402AXwLQTuP31OAZO2aG0MEn14iSlnI1z3LnMk8IZYJyBwjIs'.
'/TWsVIWPJkvMFS4zMfMhUp5BsoCpAAEBLYKaMFGn00jBxnvu02'.
'35+JHmSJEnBpQEcPo38MmCxd/nS9Ry71Ga/g1W9a8gn0GsHkgA'.
'6DGjxkqb5CoO+YxF3A3p+jGjQUzoK+L/V0ADzFMwtSR8eLbAr8'.
'uXOTf9NzhTc0geSLUQcYHgYEH786RMg0zWJHV2Aitv4x/HpHVS'.
'QA2YBqTTGIUq5qkPMWaWkVwPnPtAA/BevmZcjxaaUtHh8pJJGu'.
'DpCB9FvT7A7YT7S3p5vFMNzmWo/O0MSx/Ms3TqI8r59zFTfUQe'.
'I7SBODE3tnfoIxYnNHligwik0zAzDdVpyKbA8sff5YAeMEwgkV'.
'cufQeTJzZoCsaFLKXPTnNpoUTNsSgJmNoGsuNQjIDwYD2HlnZy'.
'k++yxTKXZfKTU8zOpjhneeQYkorSmGERtIlICBKRbLX+y98YN3'.
'ADcNIm+bJD4U3pPnmbEaRgYVRTGBkDSSsmxKfY7ZLuDJA4hdjl'.
'JEgyBB2SJOvQ9RzTpNKoEwNq0CNFvOXR3/HxMgYVPObaz8kPmh'.
'hkEWMatAfRONGGvLizyOE9P8KkpwhPDAgQKJQbELUD0oOIhbbH'.
'JeVTmowxjAgZutB5AoOngA+2DdYrcTyOyYZP9+QpBvI29vwEhb'.
'It042BVQgDy9KTMfkwQG1A9ACCLlgBBGUwxxoc52WDh2ATyEPp'.
'1hoaPvrEBh0Dq5an9OUsl/9hylk5b5c+mowLc4E2Jtw4Eoljyf'.
'ogA/AGEAagNRjGyUxOmEycyVA5EWDBxrmUp3ytLIv/NJP69Goh'.
'+9mFydIvS5PZYkvH1oY/RFtKymlwBFQAgQd+kAA6qSQ8pvn2mp'.
'SkJkuVFHPHBnQMrEt5Sl+e4/Lvp51PF1PF5Xy6WMvOWZXMom8z'.
'OZTQ8+j5sbQiMEwopsCIwRtBGIJSCdzbTGo9NimkDcgdC7Bg49'.
'TG5n4/nfr0Si77WdYp1YzyZEkWPdteaEnB7pPqBTxuIf/VgciE'.
'SgasCPwh+GNIkaNNag1RiPge5pEhMQVjfoLcF+eoXSvbKxedwn'.
'LKzC3KWbOi5/sW5a44/SHFUSgVA7SCzRG0AvA9mPOgFIETgu4n'.
'Ww0wNQWFAqRSL6D2ZQYBdDrQ7R7jXiwgRcvIL02makuTmWtpM/'.
'+BlLMl5vuWzLVEuwH6oYnR1KS8kJINGXMM2YdfRlALoQoQQKeb'.
'bDVwoMdxQMaLCwLo96HZTF5HbrEhmOftianfZisfzueKv7ZmrX'.
'MsjhxKXZGBjzyeEHmSE3oWiggtyVGmE8DTIXTC5NxgAxOAGUM8'.
'fun9mnSSLQ/CxNzOTgJ3LIMgoGwkKBiiMyaVviHVkdCO4FEKNv'.
'LQzWBYHfITPa4UBVM0LR/WB7ARJsdDDTjA6deYFIFUOimJ3d0E'.
'sNdLavYYgBpthqKcjiiJRO8K6CK0CsJTjfQAGaJtD9vQFAxNNQ'.
'1FB0yBAfA8gdMAIagLoCVAen0M00zMOTYShNDtoHs9CAIUoI4E'.
'1IBihCdNhsMhsj6NuV7BCC2IBpBqQaaFOENCCeiEsO1BO4RQgy'.
'I5Hm4k4oIU9MrgZSAdBeTabZz+ODxKQRRBFBJo6IUc51anYRQo'.
'dto+24FNxYCiaWKkQsj00KkO4gxRRkAngJ868M0u3OkkM+hxQA'.
'cQ7YD7GO5XYSsPZybh/TCkFIYY+kWniTW4Q7jXgHvHMhiRpmuW'.
'ca08GZkkZ/nY6TZMNhCnf2CuPoDVJvxpB+q9BHA8Ag1uH+oP4c'.
'YEPCzDwmzSLquShHW/E0YRbG/BjZtw40hAy7aNzJlzRn75E6N0'.
'qiwTzafI7kOU3gWrhzZC2iHcbsPqLlxvJnCt4KC1RYAL3I5hzY'.
'Xv/huePYCtITQMKEnyB4KQvMURuJvw889HGSwUCs7CwkLpo6tX'.
'Ty/+7nel6VLGDn/8N9m+eZuo1UP8iNhLau6b3RfmOsHBGTUYw9'.
'WBNeDrGB4+h/4qNLKwTnLbHj9CJw/6GoIh9Jpvq0HHcayFhYXi'.
'l3/4w9LK8vLKexfma3G/mb/3n1njTivS7tNQaaU1grQDjJ868D'.
'Axx6vmxnBrY9C9IcSbSXbavNjb/S3eN6/0m1JcKBScixcvllZW'.
'Vi6uLC8v12q1v/M8b/HxVjP//YYr32yE4dYWvShO0ogi14xwxq'.
'F4rbnxZ3cMjtpvEEeMvwA0TdOYn5/PffHFF7Vr166tvPeLXyx7'.
'nrd4+/btyg/frFo//Xgncnd67qCn78earQqcmYD3fSi1wPCTSV'.
'3gzqvm9uFOMl5nUAqFQn5paal26dKla57vf7D+6FHph9VV88af'.
'vgq79bo70e3VT2l9A3hYg4UiRALVHTCHSZvYBm4A//6quf8zoG'.
'3bpuM4acMwKr1+//SDe/dK31+/bv90/Xrcq9fduNW6rbVeC+E7'.
'gWdD2DKg4UEpBmPcm10RuScida31ntb62HAigoigDw6Gh0axWH'.
'QWFhZKi4uLZ+I4PrVer2e+u37dXPvqq6hbr7tOp1NXWq89h6/b'.
'8FBB34WGBesdcPrj38lkMkGlUuml0+mu53nR3t4eo9HoSLhMJk'.
'OlUiGdTuN5Hq7rvgA0TdO4cOFC7vPPP6/VarXldqdTu7m2lrv7'.
'7beq++BBO263b/tKrfWSXlbvwJ6CuAtDgTYiaBFMw6BSqfDxxx'.
'+rarWqGo0GN2/eZGtrC6XenAkRoVKpcPXqVWZmZmg0Gty6desF'.
'oIhIOp3Ol8vlmmVZK3fv3Lm09uc/Zwbr653ccPgoNIzvnmn99Z'.
'7W9QG46lAaM5mM2l95GIYUi0VOnz7N7OwsWmsymQzyuse5Q8Mw'.
'DNLpNDMzM5w/f/7A6AGgUkoajYa9urpayOXzUz/fvZutr68Pim'.
'F4/2y1+n2o9Q/ru7uPesPhXnyo4A+vfHp6mmazybNnz9jZ2UFr'.
'TbPZJAhe+8/aS0Mphed5NBoNABqNBqPR6MWBVWstvu/nnj9/Pv'.
'vo0aPq5uZmPBgM/qcwPf39xV/9ajU1M3Nvq9PZaw8GoT50PjdN'.
'k6mpKa5cucL58+eJ45j19XWePHnCzs4OnudhmiaWZRGGIVH05r'.
'yEYYjrumxubrKxsfFyDQJ6NBp1Pc+7C4jWumBaVm+kVL2l1H2l'.
'1G6otS+H6V6z8u3tbVzXpdFooJRicXGRqakptre3uXXr1ltrcT'.
'Qa8ezZszemWAE9rfUdYBOwtVLRbrPZ+48ff+wDvuu6Sr3MB4Dr'.
'uty6desgfa1WC3iRyrNnz4pSSmezWUzTfGtYtNYcdvC/9sMlgP'.
'n5N4cAAAAASUVORK5CYII=' ;
//==========================================================
// File: ppl_pink.png
//==========================================================
$this->imgdata_large[2][0]= 2779 ;
$this->imgdata_large[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFQolY9lkpgAACmhJREFUeJy9mOtzFNl5h5+3b9'.
'Mz0kzPBWmEVtIiWYhIiC0HCDhB8lb8ISk7nzdZ5+/zJ/8BTmpT'.
'660CZLwG1pVFgBkgGIHECEaa+/T9nHzQCCQuRpCNz6mp6g893U'.
'8/c37ve3qEjxiC4OA4n/Lp/EUu/tsMM/+aEWduVBx7WhdkShcY'.
'xUH2zo0Dwod/5N6vf8V//PoGdx8M8EOFPtK9jI8BdHCcMuVSmf'.
'LxHLmSZdm2U8xIbmKETDGDZZnIy4dBbCynyGhphurEDBOlHFnn'.
'qPcyPxTOwDCOccw7w5nlBRZWylI+ny/mZ6rL1dzUZ5/IWGZU3D'.
'ZIOMQDDaJcHDVGWUbJBi9odVr0QoVSPzigIEaZ8vgSS/8wZU3/'.
'k1fylipz5dLM2WlrZqHKaGCKbEbontq3KAKWQyZfZKTgYqc9Bp'.
'2I2PcJ4ogk/UEBQcwipbFZmT13vDBx8fhnE1Ofnp9yJopFyT3X'.
'yANfks0QHSQMDaL37pOxMLIu2UyVkjVKLjyKSeuD8dAYCFkso1'.
'gYMaeWJ40T56cl8yAi/O4FSa2P6kYczIDsgVpAqcDImZPMuAB1'.
'dkLQtcc8a/bwox8IUHAxZVxGZMouSLVYwKuMkD5IxN+JSdsRJB'.
'pexuTVgYYM6EoGmxkmg3/hEhNUMr/hd7dqbOzExMn/GRDAxWZc'.
'j3I8HiXfMjF2FQowKw7pjoN6E/Llw/GBJj8qxVOMlX4ipxc/lY'.
'kl2zBLkmrTcEzMkoNoRLVidLi/9g+Z3I+1xRHX5EcAihxnbPRv'.
'OTU9kZSmpKPy9FTGrLimPZ1H+UiyGaF67w6n7E1DwMngFDxGvc'.
'w70v0xZUby5IxjlIyMssUJrJwVWkXBdbXvSvwEibcSdKCAFI16'.
'4/sc0SRo9cGAGq1DwvQFzV6DVuBiV4zYnlEts6A2TSPcSiXoxo'.
'QqJCEEFMbQ2b69o5qMiOOPqIMQkagu/aSL7waE8101WFShLjk9'.
'yxgEvjRUiyYd+gwAjY2J9VpXfZ/JEXLhDp3OR6U4T97+hEnPwx'.
'tv4HsRjy2tTQSFzQgDUnwSLBQRI+x1ZgcH87Vcv4SF19Kt0ezS'.
'1h9s0Ma25pgr/YJfnLnEysok0+ezjM6EBLldGqKIJYuDRhOQEJ'.
'Oih8X9Q0xmcXNjlCofBJgn78wxVz7L2YWf8tPPz1hnfjbjzfxN'.
'qVwutq2etZXUQSXikcXGIgUiUkJSDIQMJgYGJsaB3c7b1qQ4GZ'.
'xSkdGZIwMeNLfK6uezMnvJK3pLxeVixfvMsyVjSNSO6IV9adPG'.
'AArkEEz8oUkFmBjYGO80qfd6pCWIayD59wIKcsjcKqufn7JO/S'.
'xfyi+5c24pey5rZ09mJRNkiDdT/tzbkBr3SYkpMYpgEaIJSYhI'.
'kSOY1GhilAQk5ntDIojxCZ/kf87Pl85xbuWEnLiUy+cW3NNuJX'.
'MmY5meKf6mT7wZS+THdOjxlG06tIlIOMZxchSxcFFEGAwAGGME'.
'jwyZYSnWL3cXWiIUbUI6hO/vxXuFOV84ycmlBWthNeflTjuzTi'.
'lzJmM5s46Ej0J63/ZoPmoy6PYxtYVNhmfs0mbAND1mmKVMBY1L'.
'mxA1LN7WgXQbCApNhKJHRIM+DQbv7yQGhjnJ5NgFuXBuxpu5mD'.
'udm3LPuY7pmZLUE6L1SIJaIPFuDAqyw9lnwDYv6NFHkWJh4ZDB'.
'wCBFD3uMxsTAwcBAiElpE/KcPg36dIiOvpsRxDCyhmlP2YY9ZU'.
'v8NMb/1id+FGO0DTztkSXLOONUqeITsMkW2zwnJEIDFhYGx+A1'.
'kwK4mASkvKDPc3p0iYhRRwYUhZLUTyV6Eu0t4s1Y4kcx6W6KaM'.
'EZThcXH59RRhGEgIAddnBwNEBKqqpUtWBIF22YDIhJsbEkJqFN'.
'qLtERHs7GnUkwISEQAf0uj30bY39PzbiC6qrDu2cExJ69Nhhhz'.
'59UlIUipCQOnVi4sjG7ubJBy6um0C+he/0iDHQKIQERYyKFLqr'.
'SI/W6kJCnvOcrWSLSquC1/Jw9Ks3R0FQKHr0uMc9bnCDGjX69A'.
'H0XlcJkibN5jOe/alCZStHbjJL9lSMLkXExvCXRiDV6GZEeGeX'.
'3TvvBVQoEjfBL/v0rT75Th7VU5C8gktI6NLlMY+5yU3WWGODDf'.
'r098tHpNFNH7/2lKdXXdz7efLzVaqJIBOCmK8AJUlI6g0aV+9y'.
'9+p7AR3bMQpTBWPy7yeN6fy0jNwewfpvC9Xe+3kFoUuXe9zj5n'.
'BusEGHjh6GIAGawC2FWuvSvbbF1maFylZAsC1ISZADBiVNSJrP'.
'eX73MY//skHP85z5+fnSxQsXj//4n39cmnPn7LbZlsajBmEnBL'.
'1nuEGDG9x4aa5Ldz+h0RCuBqwBv1Wo+7vs9r7n++0MmYeAM+zB'.
'+61EK1QUEnbbtN+9Bh3Hsebn54u//PdfLq9eWl2ZnZ1dSnaSwu'.
'Pin40b9g3doKE0WoNIl65xj3v75njd3BBubQi6ExKmDWkMRKSl'.
'tSbVKQcMao1Go5Ugb0+x53nOyZMnSysrKydXLq1cWlxa/McgCB'.
'Yev3hU+GPrD3I5/q94k3pXYQY58q6B5Bs0HB//neaGx00gyWaz'.
'VCoV7bquCoKAnZ0dfN/f03egLGj0m3XQNE1jdnY2/+WXXy6trq'.
'6uzP3oR5eCIFi4detW5feXL1vr679Let37zVB3/mQytjXJwmSB'.
'wikHp9ShY0RESqObwPrr5oBERKhUKly4cIFqtUq9XufmzZtsbW'.
'2hXvuDwTTNtxZq8TyvsLy8vLS4uLgahOHphw8elL69fNlc++qr'.
'uFOrNXPddm1cczVL5f5P+Lv5MuOJgTGxwYbZpZsCdeAq8M1Bcw'.
'CGYeC6LtVqlRMnTjAyMkKn0yGXyx0N0LZt03Ec1zCMSrfXO37v'.
'zp3S769csb+/ciXt1mrNdHf3ltZ6Lca8ZpJsduhtCdb2gEFJoQ'.
'xADYHuHDS3f32lFEEQUK/XGRkZoVAocP78eZaXl9FaI/Jq25Uk'.
'yWHAYrHozM/PlxYWFibTND32sFbLXrtyxVz76qukXas1M61WTW'.
'm99gx+20TdN9jqtfjP7QzOwwYNp037Zd0DukDnIByA1pqdnR2+'.
'++472u02Z8+eZWJiAsMwDsEBRNGBzYJpmsaJEyfyX3zxxdLS0t'.
'KlVqu1dP3q1cLta9ekU6u1dat1J9b6Sk9kraV1rYXegW7apDYw'.
'kFY6fPc4MNTw88bwfZ/NzU2UUnieRxAEiAiGcXiXfcigiIjruo'.
'VyubxkWdbK7fX1xWvffFMInjzBM82uMT5+p++6V1UUrSe7u03t'.
'+8lezlKt3gHyl0aSJDQaDa5fv876+vo+w6FzDq1BpZRsb2/bly'.
'9f9vL5/Njdu3fzG0+eMJHNxsfn532vXN5NPG/7abPZal6/Hvfe'.
'kroPHfsm98f7AHW9Xo+//vrrlmVZm71+37QNw3JnZ9PK4uJGpV'.
'pt4Dh+vLGhsrmcfv1iHzu01m89HjIdCon2fb8TBMHtvYeRUn50'.
'1Oj4vqp3Ok1f5LYSadfr9dQfDN642P/XeF2DA+SBAuA4jkOhUK'.
'BQKESO43S11p3BYBDt7u4y+CtB/i/q7jp1GMiw2AAAAABJRU5E'.
'rkJggg==' ;
//==========================================================
// File: ppl_blue.png
//==========================================================
$this->imgdata_large[3][0]= 2284 ;
$this->imgdata_large[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFRAiTZAL3gAACHlJREFUeJy9mGtv29YZgJ9zKF'.
'F3y/Q9jh05tuQkarKgbYasde0UBdZgwNou/Vqga/sD9mP2B4a1'.
'BbZ9atFPxb5sqOtmXbI19bqsluPYiR3HN90vFEWRZx/IJI5zqa'.
'x0OwBBSgR5Hj7v+55zSEFXTUgIJyA9C6/9RsjMjAyFIxxJCDc7'.
'iBqKgyZACGg3G2x9+xXf/fG33P3mC9qNKsp1O+1JdkEnQTdgIO'.
'ttCSMUi8gj072MnugllAyB9G8rBGi6RsToJTF6iuRoFi1kHKZf'.
'7fB8Iggj0/Dy23D2dakNTR3JDsXPvzstxmZGRMER1EwHhQAEgE'.
'CLhIkPD6InY9S3djGLJVBtQP1Qb4HDAyoJYQOOZkPx49nhTH9i'.
'7MUBGT7egxkJgd70wZS/CUkoZtA/fRoE1DZ2ACiv52ibReCp4e'.
'7CIEHomxDiuVdGTqUnf/ZeOjR8fpiVXZul5ZrY3bWwbdcLr/dA'.
'AAIpAwQjUWIjQ+g9HZvswiCgBVF9/SI6OSLGzo0i+oLi6+Utbq'.
'+bKEftgwOE/0Ohocf66M+cBjo22U2RQLIHMhmYnvaOpR9S8bSU'.
'UqCURGpRkuMZMm9cIvPGJZLj0yBjT2LprkiSkykx9cuXIhOnUs'.
'm+QNC2XdG02ggBTcvFabsPWwTPpBAChSCgh4kYBpoeplWp47Qs'.
'7EYDt21xINzd5GCAxLExRl89Z+nHjpbKMmjbmkgfDzI0JEW53K'.
'Jaa6NcAOEX8v52uJzsBlAS6u0hcnTIccPRqhWPCUcLD+s1EaUp'.
'HCEhEMCyHNpt9SjgIU12A6iw6xb123vYhaaKjB9tlgMD5X+uBp'.
'zdkpg6azA8EaNQtKlVba+Xez4eCntnJrsDdFsW5nYFpxlFN846'.
'DXe8utkM4mhi+EgQmjYbS2WqexZKk6BpjwJ2YlK5VjeA3pNDiH'.
'YjRWPzPE7tmBo8EWwGhkXx+z3uXL7D3rU97LIF8RBEAl6lK/Uo'.
'6JNM1rZ2aTcr3eUgIQOGTgbdwXMGyRejenLYTvQGbAdRuetSud'.
'OivVuFZgtCEgICghICnZoMhmlVTPR49LCAEkQUhk/B7KXe0MWf'.
'nxj8xVR/cDheK14WZmtVMJSBnlGoN6FmQq0FLfdwJgORKPHRo/'.
'Snzx4G0F/FjJ4KiOdmjPCrrx8bffnMybMv9MQGNG3rzlVqtR1B'.
'sh/CYXCD4Aag1oCW7ZnUOjSp6WFi/QNEB8Y7BfTNjZyCmUvJ0I'.
'XXT47MTp98Ybon9VZCk8cVazfqlNargsY34G7ByAlIjkHd9CCr'.
'LbBdiHViUgiECuDKYCdz8b2cywREdiYZOj8zNnLuzOTzx6ODp+'.
'OaGaqwVzBFqz0Idhz2loE7YEwBLaAJLQcKbW8qjAcBF5Jh0AMP'.
'IOHe6kxgtb3UMO2OxkF//ffK28nQqxfvm3szrtnDVa799Qb/+v'.
'NtsbNSpm3tAv8B+w7Ub0FhAyoBcMPec9oK6raXk48ziQBXQcmC'.
'pT3YqHa0mpEBkTR6wz/Jjo2cy04+fzwxdDquNfQKO7sFUbpu0c'.
'wp3JoAYsA42Bbkl4GCryUNDEM7Avm6Z/CgSYBWG8pNuFuDu1Wo'.
'tjoxKIJGeHIiM/jmK9NnX5ycuJQMtUcqXPvLDTa+qIie4hAJ1U'.
'vdrmO2HaDfB931twJgAn1A4lGT96obPHPLBbhVgUoTHHWo9aAA'.
'JVAKpyKEmQNzWRENAsL18ycKjAFN/9gCNvzLB/390MMmE7pnDi'.
'Bvwt0K5Jv3O+0oB22nJ1Vvjb/UMhOpcKknqN1OiMB2DNHU2G5s'.
'sVndpGJVcZXjX1IAlvw9PmhRQcOFPhsSDkiBrQR1G7brgs0a7D'.
'ag3FK4rguqBXarI4Nt1SJv5gls7TEWtJDRBO2GwnIs8maevFnA'.
'Gx6awLZvzeTBu4kFbLigijC47pscpx0xyDfkvtUEnlarCDtrUC'.
't2HGIhvPHVdVwqjTIrxRU2a5uUrYoP0QZ2gMvACl7+3V/LuKDq'.
'sJuDy597516+CEezIHXv7vcgXQu2l+Bvn8He9Y4AE4kgk5P9DE'.
'R6aFdq5Et5Nit3yTf3m9sBcsAN3+D98c0Fit5JawE25r1zg1Fo'.
'5B8GFD7g+nVYnu8EUEop9XTa0N/9dUbqcphP/rDJzbUClVbpgR'.
'y2fXM3fND95qj75J8AC6BWPINfVSBieK+x+6cS5UCzCLu3oFV9'.
'GqCMx2NGOp2Znpv7aXZudsool3T5J/179sxVlHJ4kGPrP2COBX'.
'/7DmiApWCjxIMXpYNznYuXM+6TAKWUMppOZzLvv//ery5cuDCT'.
'SqVS336bCwr1JfAPB9r+2KAFwJS+OcETzZHz/7v3etl6ipz77X'.
'GAMh6PG+l0OjM3NzczOzs3k0pNnFlbW43+e/GKtMqrblSsF03V'.
'WHcJA0PjIAzvg9JTze2H67g9DjAwOTmZ+uCDD96anZ2dnZiYmF'.
'5dW41++Lvfa1fnr7qllVK9103mXNTnJgPA+YugsvB3HTaEl+Qs'.
'AZ/yeHPPDCiTyaRx5syZbGoilV1dW00szC9oV+avusuLy0Xd0X'.
'MgFkDM+zkYBZEHV8f7wwKu84zmngQoNU0LaZoWUa4K31y5qX/8'.
'4cfyyvwVN5/L10NOKNeg8UmDxoKF5Vfj1xXAgD0JrgAcvBDfel'.
'a4g4AykUgY6XR6emJiIru2ttZXq9S0K19eUcuLy8WQE8o5OAsN'.
'Ggsmpl+NpoL1g9X4UBU+C9xDgEKIwNTUVOqdd955M9mbnJ3/cj'.
'6Vu5aTheXCQXNdVeMzAwJSCGEA2XKpnF1cXIzlFnOVhJPIKdR+'.
'c88ctq4AlVKsrKzw0UcfKcC5uXqzXnNqSzb2pwLxOHP/l7Z/BN'.
'eB01LKt4HTrusKvGr8jB+hGn8MQAkYQMrfw4Nq/MFPtf+rdvDb'.
'k8QL+/5Z4Uepxm7bfwHuTAVUWpWaqAAAAABJRU5ErkJggg==' ;
//==========================================================
// File: ppl_green.png
//==========================================================
$this->imgdata_large[4][0]= 2854 ;
$this->imgdata_large[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFQ4hANhluwAACrNJREFUeJytmF1zE1eagJ+3u9'.
'XdkvUty2AbmLEtEzDBgZ0UpDBOalNTUzU3czl7tct/2n+wt3M/'.
'NVM12SSTQQSyW2TA+QAJQogtYYFtyfrqL3WfvWj5g8AEjzfvhS'.
'SXjk8//Zz3Pf3qCMcJAWxMKlT4kH+jwu/FknnJSUItKFHzCrKA'.
'BggBQx5ziz/wn/yBz3hED4/oaJfSjgVoYjJJgTLTZCjohp7IGT'.
'k5aZ4kb+bRTR30Q7djj8f/kpPMUSCFedRL6W8e8qMQNE6S4xpv'.
'c5HrTPFubiJ3ZnlyOXV59rJYU5Z00h1c3d0brxAiUkScRijisk'.
'6XLTyiN3s8HuAJpniXa/q8/pt8Or+0kF8oXJm5YiydWcIpOrJu'.
'rjOQwd54AQwsMpTJYhPSoYuLQ58An/DnBQSdImXO8avsTPbqpc'.
'lLp67OXDVzMznZLGxSs2qyIRu4at8gKHQEC50kE1icxqCAdxST'.
'xjEA44tqaJlERl8uLWvvnX5PHuQfcCdxh5qq0aX76vj4WgWyXO'.
'QiNgBP8IAaddr08X8+wHFmJSQhBbPAZGoSZSt5wQs6qoNC7UEd'.
'4AEoLIQSCaCCy78Dv8Tiv1hjjW1CRj8XIAgEKqDtt9keboMJZa'.
'vMjuzQVd3Xr9prTJo+GF/jKZea95R25Lxs8jg5qFGiwDnOS0mW'.
'NE0rjNRIt3WbklUCA9mV3Zdz8OBT/JfCQLB0SKYVVjGFYSfx/E'.
'26ow4e6uDujlPFQpE0FU6P8qNTHdXJdEdda0qf0itWBVM3pa/3'.
'ccUlIECJet0cAJoeYk5EZCeS5IwEoerSxccJBwRqFFf38QCTaO'.
'TRVFKJm3NTbtLNSyh2IkhIXsvLCesEGNCWdmwyruSD/z9kUlRc'.
'3bqNlSxhJNJ43p5JITrOEis8Qtr0cXEpU/JT/pmO18n2vb42pU'.
'3JnDnHMBqyPlpnoAaxhr2llv1ZUBqEGlqYwDQMsskMOcMgVL3Y'.
'ZOQTHAcQQiIGjHCwCaiovjrv4hbcpKuJJjIcDHm685RGr4GLCx'.
'YHkAcrLoAoDSLBiAQrMkjqybHJCbxgh+7xAC1MpsgzwRwD3qHL'.
'WyTIBdlAa6u2rHfXaew06PV78ZZjAwleNnkolECoH5i090wOcY'.
'+TgwYzFHiPi1zkOkXexeAMASnVU+LiyiA1wFUuaqggACLizeWw'.
'ycMzyssmVYKkbpGyC5T+OUALk2mKLHKWf+ED/az+YW42d66YL+'.
'aNrmEEzQCFEnKw368EgEvcN1m80eTIQIt0TFOjMJHkzNEBBYPp'.
'sblf8QHzrORO5JaWZ5ZLl6cuJyyxpNPv4PZdoT+GyIxBfI5uUg'.
'eJMCwP2/bIHO1JEudcgUUWOceKNq99mCvnzs5PzRcuTV4y5mRO'.
'SMIjo47z5S7a94oQCNKgJsZwO7D/IDNg3/LLhRNXt4JohBb4aG'.
'82GLdXcf93mQ+Y43r2RHZp+cRy6cqJK4l8MS+tdItaqiYtc0Mm'.
'QpfJARh98HYh9IiXVcaAo58wGb+LBAjbSPgCOcoSa0wzxXtc08'.
'/pv8mfyL+9MLVQvDJ1JVHJV6SZbFI1qtTsB+KlehRtRTGE8Afo'.
'P4DRcAxiEudhAHjjzz+ubgX4oHowakHQOlqzICQwyVPITGVOXi'.
'xfLF6aumzmczl5lHzMff2+fCdPaGttEkXoLQAO9B7C6EugPYby'.
'gVPjGXc5eIbNAJPjGwiAbaAJUQv8wVG7GROkJFpyOqn/ovgLba'.
'44L0+sDaraXb6jzq7aBQWjBOyUoHcaopOgmaA3IRyNDZnA1HjO'.
'HSBkr7eEFDAEngHrQCf+/s2A8cSiSkqcKUeeTjwFy2Jd78t3+L'.
'TR4itIiBLwLQhzkJyB5Cx4HXDaENVQCBAQcRqFIHTRaBIvuYXg'.
'AdsouuNxEL0ZUBHnSQp66R73zYfUtQ6OytKT8RckQAJQoLtgO5'.
'BJgj0D/WfgdyHaAHx8THoUcbGx8ciwhUl3bDEiToURPooeI7pH'.
'MziK9Yd9nU5a6GgKjOH41vsgI4hAcyC5AZkapF+AoYNrjjsuhx'.
'FbtPmeB5ykyQQzTPAWAQWC8S9oAI0QRRuPb9jkmyMZNAOTklvC'.
'GGYZaFkGmkVAh8h4DtKFMIBunG+pB5B5AIkGBDsQ+qBiL20caj'.
'zhJknq5KlgMkLjJHJos4kYEbFJi5vc5eYbATVN02bNWe19+32t'.
'aJWlFm3wbf8Rz5NbDFJdlOFBF/g7cBf0JkrbBb+F6j1DOduEkU'.
'8bWCOiSofPWadBnSZDWmgUkEMGhZCINut8S/0NBtPptFlZrBSu'.
'vnt1+ndnflfIp9OJ/279Ubbbd+lP7KBKPoEBsgnqLph/BRzwdS'.
'LnBUFvHcfdpRsGPAGqwMco6jynz+e0SPKYCHMfLX5VKHwcenR+'.
'Igd1XTcqlUr+xn/cePv91fevzy8sLO2OtrOpWkqL7gXKSAVRdh'.
'ZFEmEXoYkwBNqovoc/3GHH3aUR+jwC1oD/AWrANi4hGwyBzqEG'.
'Vvb77Dgi0eT1VZzJZMxKpVJYXV1dXF1dXVm6sPSvruue3Xzcyj'.
'6/syvDzwj0lNazK6Fj5LFCRZouZpBABj6jXouu3+Np6HNvDHaf'.
'g91t74msbMuOJicnSSaTKKUQEUQEpRSO69But1/dB0VEm5uby9'.
'y4cWNpdXX1+sLCworrume//PuXpeqnVeOban0U1PW2kcx+O9L7'.
'Te9sUB4lWFR9SqNtNGcHx+/RDD2+Am4D94CnQA8OjjlEhMnyJC'.
'srK8zOzu7BiYioMAzZ2Njg9u3brwIqpSSXy2WXl5eXLly4sOo4'.
'zoV6vV6oflrVP/7Tx8Hmw1Zb6ydqmpWp7ha8h4O3gjOhzVANmF'.
'XPMNQWvdDnCXCXuHR+APqH4fbCtm2mp6eZn59H13WJuYXRaKSU'.
'UiSTyVcBdV3XDcOwRaTU7/en19bWCn/79G+JL/76RbhZ22y7u+'.
'6ahl71nPDz/nO17m7wAxlabFOihy4+DvAcqAMbPzZ3OFzX5dmz'.
'Z2iahoiosUUVhiGNRgPHcV4GzGQy5uLiYuH8+fMzo9FoslarJW'.
'9+elP75E+fBJu1zY7qqpqBUW3T/niohnVvy+1zm5aVtp+WE2XT'.
'nrHFzbjh1tYLz3XdPjD4R3BKKba2tqhWq4dzUO3noBPn4H5PKy'.
'LaO++8U7hx48byhQsXVne7u6tf3/v64t3P7mbq9+odt+OuaWi3'.
'PLxbW2ytubjbQCgiMnt6VlaurWgz0zM0m02q1WrUaDSUUuqI56'.
'ivDxE5MCgiYllWtlwuL5mmufLV/a/O/uXPf9Ff1F+80Lv6Yx29'.
'2qHzyZBh3cdvc7gaTZuZkzPh/Py8ACqVSv1/uPZDKXUAGEWRtF'.
'qtxEcffZTL5XLF+2v39fqjeivshA/TpP83JLwzYFBzcA4370Cc'.
'S81nTRBUs9lkOByi1GuOPI4Rh3+26JZlnSkWi781DOPXvV4v3+'.
'/2G0R8kSBxB/jew+tERK+c49m2TblcxrZtXNfl+fPneJ6HZVmU'.
'y2VJJpNyaJ9TSinlOA5bW1u4rntkQA0oAG8D54gb9W3ianxM3A'.
'e/cn73U3Hq1Cm5du2aPjs7a+ztcSIShmE4ajQa6tatWzQajZ+0'.
'fbiKI+It4SvijVUj7kL2qvGfgkskEqTTaZmcnDROnTplJhIJTU'.
'QiwPd9P/Q8T6XTaQzDIAiCfzjP/wFVfszuFqdHXgAAAABJRU5E'.
'rkJggg==' ;
//==========================================================
// File: pp_red.png
//==========================================================
$this->imgdata_small[0][0]= 384 ;
$this->imgdata_small[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'.
'B3RJTUUH0wMJFhouFobZrQAAAQ1JREFUeJyV1dFtwyAQBuD/og'.
'xQdYxa8gRY6hJ0jK6QdohMkTEuE5wUj5ERen05IoLvID7Jkn2G'.
'j8MgTMyMXqRlUQBYq9ydmaL2h1cwqD7l30t+L1iwlbYFRegY7I'.
'SHjkEifGg4ww3aBa/l4+9AhxWWr/dLhEunXUGHq6yGniw3QkOw'.
'3jJ7UBd82n/VVAlAtvsfp98lAj2sAJOhU4AeQ7DC1ubVBODWDJ'.
'TtCsEWa6u5M1NeFs1NzgdtuhHGtj+9Q2IDppQUAL6Cyrlz0gDN'.
'ohSMiJCt861672EiAhEhESG3woJ9V9OKTkwRKbdqz4cHmFLSFg'.
's69+LvAZKdeZ/n89uLnd2g0S+gjd5g8zzjH5Y/eLLi+NPEAAAA'.
'AElFTkSuQmCC' ;
//==========================================================
// File: pp_orange.png
//==========================================================
$this->imgdata_small[1][0]= 403 ;
$this->imgdata_small[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'.
'B3RJTUUH0wMJFhwAnApz5AAAASBJREFUeJyN1dFthDAMBuDf7S'.
'3BCm2VCRKpS4QxbhikW6IewzcBqm6Fm6JyH7iEEByCn5AJH38g'.
'BBIRHNUzBAWAGNfe/SrUGv92CtNt309BrfFdMGPjvt9CD8Fyml'.
'ZZaDchRgA/59FDMD18pvNoNyHxMnUmgLmPHoJ+CqqfMaNAH22C'.
'fgqKRwR+GRpxGjXBEiuXDBWQhTK3plxijyWWvtKVS5KNG1xM8I'.
'OBr7geV1WupDqpmTAPKjCqLhxk/z0PImQmjKrAuI6vMXlhFroD'.
'vfdqITXWqg2YMSJEAFcReoag6UXU2DzPG8w5t09YYsAyLWvHrL'.
'HUy6D3XmvMAAhAay8kAJpBosX4vt0G4+4Jam6s6Rz1fgFG0ncA'.
'f3XfOQcA+Acv5IUSdQw9hgAAAABJRU5ErkJggg==' ;
//==========================================================
// File: pp_pink.png
//==========================================================
$this->imgdata_small[2][0]= 419 ;
$this->imgdata_small[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'.
'B3RJTUUH0wMJFhsQzvz1RwAAATBJREFUeJyd1MFthDAQheF/oi'.
'gF+JYWQKICkCJRA1vGtrDbxFbhGvY0HVjCLeS2BeTiHFgTB2wg'.
'eRISstCnmcG2qCpbuXf3ADBQzWsPfZfS9y9HsEu4/Fo33Wf4Fx'.
'gxL3a1XkI3wbTNXHLoboVeLFUYDqObYBy+Fw/Uh9DdCmtOwIjF'.
'YvG76CZoOhNGRmpO8zz30CJoOhMAqlDxFzQLppgXj2XaNlP7FF'.
'GLL7ccMYCBgZERgCvXLBrfi2DEclmiKZwFY4tp6sW26bVfnede'.
'e5Hc5dC2bUgrXGKqWrwcXnNYDjmCrcCIiQgDcFYV05kQ8SXmnB'.
'NgPiVN06wrTDGAhz5EWY/FOccTk+cTnHM/YNu2YYllgFxCWuUM'.
'ikzGx+2Gc+4N+CoJW8n+5a2UKm2aBoBvGA6L7wfl8aoAAAAASU'.
'VORK5CYII=' ;
//==========================================================
// File: pp_blue.png
//==========================================================
$this->imgdata_small[3][0]= 883 ;
$this->imgdata_small[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAACi1'.
'BMVEX///8AAAAAADMAAGYAAJkAAMwAAP8zAAAzADMzAGYzAJkz'.
'AMwzAP9mAABmADNmAGZmAJlmAMxmAP+ZAACZADOZAGaZAJmZAM'.
'yZAP/MAADMADPMAGbMAJnMAMzMAP//AAD/ADP/AGb/AJn/AMz/'.
'AP8AMwAAMzMAM2YAM5kAM8wAM/8zMwAzMzMzM2YzM5kzM8wzM/'.
'9mMwBmMzNmM2ZmM5lmM8xmM/+ZMwCZMzOZM2aZM5mZM8yZM//M'.
'MwDMMzPMM2bMM5nMM8zMM///MwD/MzP/M2b/M5n/M8z/M/8AZg'.
'AAZjMAZmYAZpkAZswAZv8zZgAzZjMzZmYzZpkzZswzZv9mZgBm'.
'ZjNmZmZmZplmZsxmZv+ZZgCZZjOZZmaZZpmZZsyZZv/MZgDMZj'.
'PMZmbMZpnMZszMZv//ZgD/ZjP/Zmb/Zpn/Zsz/Zv8AmQAAmTMA'.
'mWYAmZkAmcwAmf8zmQAzmTMzmWYzmZkzmcwzmf9mmQBmmTNmmW'.
'ZmmZlmmcxmmf+ZmQCZmTOZmWaZmZmZmcyZmf/MmQDMmTPMmWbM'.
'mZnMmczMmf//mQD/mTP/mWb/mZn/mcz/mf8AzAAAzDMAzGYAzJ'.
'kAzMwAzP8zzAAzzDMzzGYzzJkzzMwzzP9mzABmzDNmzGZmzJlm'.
'zMxmzP+ZzACZzDOZzGaZzJmZzMyZzP/MzADMzDPMzGbMzJnMzM'.
'zMzP//zAD/zDP/zGb/zJn/zMz/zP8A/wAA/zMA/2YA/5kA/8wA'.
'//8z/wAz/zMz/2Yz/5kz/8wz//9m/wBm/zNm/2Zm/5lm/8xm//'.
'+Z/wCZ/zOZ/2aZ/5mZ/8yZ///M/wDM/zPM/2bM/5nM/8zM////'.
'/wD//zP//2b//5n//8z///9jJVUgAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAwkWGTNerea3AAAAYUlEQVR4nHXNwQ3AIAxDUUfyoROxRZ'.
'icARin0EBTIP3Hp1gBRqSqYo0seqjZpnngojlWBir5+b8o06lM'.
'ha5uFKEpDZulV8l52axhVzqaCdxQp32qVSSwC1wN3fYiw7b76w'.
'bN4SMue4/KbwAAAABJRU5ErkJggg==' ;
//==========================================================
// File: pp_green.png
//==========================================================
$this->imgdata_small[4][0]= 447 ;
$this->imgdata_small[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'.
'B3RJTUUH0wMJFhkLdq9eKQAAAUxJREFUeJyN1LFVwzAQxvH/8f'.
'IeDS0FLKABlN6eIwPYAzCHB0gWYI2jj+i1ABUTQN4TRSQ7iiWZ'.
'qxLn9Mt9ydmiqrSq930AYFiu6YdKrf/hP1gYQn6960PxwBaYMG'.
'E9UA3dBFtVQjdBOQmBakLennK0CapRwbZRZ3N0O/IeEsqp3HKL'.
'Smtt5pUZgTPg4gdDud+6xoS97wM2rsxxmRSoTgoVcMZsXJkBho'.
'SmKqCuOuEtls6nmGMFPTUmxBKx/MeyNfQGLoOOiC2ddsxb1Kzv'.
'ZzUqu5IXbGDvBJf+hDisi77qFSuhq7Xpuu66TyJLRGbsXVUPxV'.
'SxsgkzDMt0mKT3/RcjL8C5hHnvJToXY0xYRZ4xnVKsV/S+a8YA'.
'AvCb3s9g13UhYj+TTo93B3fApRV1FVlEAD6H42DjN9/WvzDYuJ'.
'dL5b1/ji+/IX8EGWP4AwRii8PdFHTqAAAAAElFTkSuQmCC' ;
}
}
?>

View File

@ -1,151 +0,0 @@
<?php
//=======================================================================
// File: IMGDATA_SQUARES.INC
// Description: Base64 encoded images for squares
// Created: 2003-03-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: imgdata_squares.inc 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class ImgData_Squares extends ImgData {
protected $name = 'Squares';
protected $an = array(MARK_IMG_SQUARE =>'imgdata');
protected $colors = array('bluegreen','blue','green',
'lightblue','orange','purple','red','yellow');
protected $index = array('bluegreen' =>2,'blue'=>5,'green'=>6,
'lightblue'=>0,'orange'=>7,'purple'=>4,'red'=>3,'yellow'=>1);
protected $maxidx = 7 ;
protected $imgdata ;
function ImgData_Squares () {
//==========================================================
//sq_lblue.png
//==========================================================
$this->imgdata[0][0]= 362 ;
$this->imgdata[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAIAAADZrBkAAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFgojiPx/ygAAAPdJREFUeNpj/P377+kzHx89/c'.
'VAHNBQ5VBX52HavPWWjg6nnDQbkXoUFTnnL7zD9PPXrz17HxCj'.
'E6Jn6fL7H7/+ZWJgYCBGJ7IeBgYGJogofp1oehDa8OjE1IOiDa'.
'tOrHoYGBhY0NwD0enirMDAwMDFxYRVD7ptyDrNTAU0NXix6sGu'.
'jYGBgZOT9e/f/0xMjFyczFgVsGAKCfBza2kKzpl3hIuT1c9Xb/'.
'PW58/foKchJqx6tmy98vbjj8cvPm/afMnXW1JShA2fNmQ9EBFc'.
'Opnw6MGjkwm/Hlw6mQjqwaqTiRg9mDoZv//4M2/+UYJ64EBWgj'.
'cm2hwA8l24oNDl+DMAAAAASUVORK5CYII=' ;
//==========================================================
//sq_yellow.png
//==========================================================
$this->imgdata[1][0]= 338 ;
$this->imgdata[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAWl'.
'BMVEX////+/+H+/9/9/9v8/8P8/8H8/7v8/7n6/4P5/335/3n5'.
'/3X4/1f4/1P3/031/w30/wn0/wPt+ADp9ADm8ADk7gDc5gDa5A'.
'DL1ADFzgCwuACqsgClrABzeAC9M0MzAAAAAWJLR0QAiAUdSAAA'.
'AAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEDlOgDj'.
'EAAAB+SURBVHjaVcpbCsQgDEDRGERGKopjDa2a/W9zfLWj9/Nw'.
'Ac21ZRBOtZlRN9ApzSYFaDUj79KIorRDbJNO9bN/GUSh2ZRJFJ'.
'S18iorURBiyksO8buT0zkfYaUqzI91ckfhWhoGXTLzsDjI68Sz'.
'pGMjrzPzauA/iXk1AtykmvgBC8UcWUdc9HkAAAAASUVORK5CYI'.
'I=' ;
//==========================================================
//sq_blgr.png
//==========================================================
$this->imgdata[2][0]= 347 ;
$this->imgdata[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAZl'.
'BMVEX////0+vv0+vrz+fry+frv+Png7e/d7e/a6+zY6+250tSz'.
'0tSyztCtztGM0NWIz9SDzdNfsLVcrrRZrbJOp61MpqtIr7dHn6'.
'RErrZArLQ6q7M2g4kygYcsp68npa4ctr8QZ20JnqepKsl4AAAA'.
'AWJLR0QAiAUdSAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU'.
'1FB9MDCxYEByp8tpUAAAB7SURBVHjaVcjRFoIgDADQWZpWJpjY'.
'MsnG//9kzIFn3McLzfArDA3MndFjrhvgfDHFBEB9pt0CVzwrY3'.
'n2yicjhY4vTSp0nbXtN+hCV53SHDWe61dZY+/9463r2XuifHAM'.
'0SoH+6xEcovUlCfefeFSIwfTTQ3fB+pi4lV/bTIgvmaA7a0AAA'.
'AASUVORK5CYII=' ;
//==========================================================
//sq_red.png
//==========================================================
$this->imgdata[3][0]= 324 ;
$this->imgdata[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAXV'.
'BMVEX////++Pn99/j99ff99fb98/X98/T98PL55uj43+P24+bw'.
'kKPvjaHviJ3teJHpxMnoL2Pjs73WW3rWNljVWXnUVnbUK1DTJk'.
'3SUHPOBz/KQmmxPVmuOFasNFOeIkWVka/fAAAAAWJLR0QAiAUd'.
'SAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEHd'.
'ceT+8AAABtSURBVHjaVchbAkMwEAXQq6i3VrQiQfa/zDYTw8z5'.
'PCjGt9JVWFt1XWPh1fWNdfDy+tq6WPfRUPENNKnSnXNWPB4uv2'.
'b54nSZ8jHrMtOxvWZZZtpD4KP6xLkO9/AhzhaCOMhJh68cOjzV'.
'/K/4Ac2cG+nBcaRuAAAAAElFTkSuQmCC' ;
//==========================================================
//sq_pink.png
//==========================================================
$this->imgdata[4][0]= 445 ;
$this->imgdata[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAApV'.
'BMVEX////6+Pz69/v49Pr38/r17/jr4+/l3Onj2efh1ua/L+i+'.
'q8m+Lue9Lua8qsS8LuW8LeS7pca5LOG4LN+2Y9O2YNW1ZdO1Kt'.
'y0atC0aNGzb82zbc6zKtuzKdqycsuwa8qtJtOISZ2GRpuFN6GE'.
'NqCDQpmCMZ+BPpd/LJ1/K519S5B9Jpx9Jpt9JZt6RY11BJZ1BJ'.
'V0BJV0BJRzBJNvNoRtIoJUEmdZ/XbrAAAAAWJLR0QAiAUdSAAA'.
'AAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYDF3iKMD'.
'YAAACeSURBVHjaVczbEoIgGARgCiMtrexoWpaa2FHUgvd/tH4Y'.
'BnEvv9ldhNPradPnnGBUTtPDzMRPSIF46SaBoR25dYjz3I20Lb'.
'ek6BgQz73Il7KKpSgCO0pTHU0886J1sCe0ZYbALjGhjFnEM2es'.
'VhZVI4d+B1QtfnV47ywCEaKeP/p7JdLejSYt0j6NIiOq1wJZIs'.
'QTDA0ELHwhPBCwyR/Cni9cOmzJtwAAAABJRU5ErkJggg==' ;
//==========================================================
//sq_blue.png
//==========================================================
$this->imgdata[5][0]= 283 ;
$this->imgdata[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAQl'.
'BMVEX////4+fz39/z19vvy8vru7/ni4+7g4fHW1ue8vteXmt6B'.
'hdhiZ7FQVaZETcxCSJo1Oq4zNoMjKakhJHcKFaMEC2jRVYdWAA'.
'AAAWJLR0QAiAUdSAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0'.
'SU1FB9MDCxYDN0PkEP4AAABfSURBVHjaVchHAoAgDATAVcCCIF'.
'j4/1elJEjmOFDHKVgDv4iz640gLs+LMF6ZUv/VqcXXplU7Gqpy'.
'PFzBT5qml9NzlOX259riWHlS4kOffviHD8PQYZx2EFMPRkw+9Q'.
'FSnRPeWEDzKAAAAABJRU5ErkJggg==' ;
//==========================================================
//sq_green.png
//==========================================================
$this->imgdata[6][0]= 325 ;
$this->imgdata[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAXV'.
'BMVEX////2+vX1+vX1+fT0+fPz+PPx9/Dv9u7u9e3h7uHe697a'.
'6dnO2s3I1sa10LOvza2ay5aEwYBWlE9TqE5Tkk1RkEpMrUJMg0'.
'hKiUNGpEFBojw8oTcsbScaYBMWlwmMT0NtAAAAAWJLR0QAiAUd'.
'SAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEFd'.
'nFx90AAABuSURBVHjaVc9HAoAgDADB2HuJWLDx/2cKBITscW4L'.
'5byzMIWtZobNDZIZtrcCGZsRQ8GwvRSRNxIiMuysODKG3alikl'.
'ueOPlpKTLBaRmOZxQxaXlfb5ZWI9om4WntrXiDSJzp7SBkwMQa'.
'FEy0VR/NAB2kNuj7rgAAAABJRU5ErkJggg==' ;
//==========================================================
//sq_orange.png
//==========================================================
$this->imgdata[7][0]= 321 ;
$this->imgdata[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAUV'.
'BMVEX/////8+n/8uf/8OP/59H/5Mv/zqH/zJ3/ypv/yJf/vYH/'.
'u33/uXn/n0n/nUX/m0H/lzn/ljf/lDP/kS3/kCv/iR//hxv/fg'.
'n/fAX/eQDYZgDW6ia5AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAL'.
'EgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEJIgbx+cAAAB2SURBVH'.
'jaVczRCoQwDETRbLAWLZSGUA35/w/dVI0283i4DODew3YESmWW'.
'kg5gWkoQAe6TleUQI/66Sy7i56+kLk7cht2N0+hcnJgQu0SqiC'.
'1SzSIbzWSi6gavqJ63wSduRi2f+kwyD5rEukwCdZ1kGAMGMfv9'.
'AbWuGMOr5COSAAAAAElFTkSuQmCC' ;
}
}
?>

View File

@ -1,145 +0,0 @@
<?php
//=======================================================================
// File: IMGDATA_STARS.INC
// Description: Base64 encoded images for stars
// Created: 2003-03-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: imgdata_stars.inc 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class ImgData_Stars extends ImgData {
protected $name = 'Stars';
protected $an = array(MARK_IMG_STAR => 'imgdata');
protected $colors = array('bluegreen','lightblue','purple','blue','green','pink','red','yellow');
protected $index = array('bluegreen'=>3,'lightblue'=>4,'purple'=>1,
'blue'=>5,'green'=>0,'pink'=>7,'red'=>2,'yellow'=>6);
protected $maxidx = 7 ;
protected $imgdata ;
function ImgData_Stars() {
//==========================================================
// File: bstar_green_001.png
//==========================================================
$this->imgdata[0][0]= 329 ;
$this->imgdata[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAAUV'.
'BMVEX///////+/v7+83rqcyY2Q/4R7/15y/1tp/05p/0lg/zdX'.
'/zdX/zVV/zdO/zFJ9TFJvDFD4yg+8Bw+3iU68hwurhYotxYosx'.
'YokBoTfwANgQFUp7DWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'.
'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJj'.
'CRyxgTAAAAcUlEQVR4nH3MSw6AIAwEUBL/IKBWwXL/g0pLojUS'.
'ZzGLl8ko9Zumhr5iy66/GH0dp49llNPB5sTotDY5PVuLG6tnM9'.
'CVKSIe1joSgPsAKSuANNaENFQvTAGzmheSkUpMBWeJZwqBT8wo'.
'hmysD4bnnPsC/x8ItUdGPfAAAAAASUVORK5CYII=' ;
//==========================================================
// File: bstar_blred.png
//==========================================================
$this->imgdata[1][0]= 325 ;
$this->imgdata[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v79uRJ6jWPOSUtKrb+ejWO+gWPaGTruJTr6rZvF2'.
'RqC2ocqdVuCeV+egV/GsnLuIXL66rMSpcOyATbipY/OdWOp+VK'.
'aTU9WhV+yJKBoLAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJwynv1'.
'XVAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_red_001.png
//==========================================================
$this->imgdata[2][0]= 325 ;
$this->imgdata[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v7+eRFHzWG3SUmHnb37vWGr2WHG7Tlm+TljxZneg'.
'Rk3KoaXgVmXnV2nxV227nJ++XGzErK3scIS4TVzzY3fqWG2mVF'.
'zVU2PsV2rJFw9VAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJzCI0C'.
'lSAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_blgr_001.png
//==========================================================
$this->imgdata[3][0]= 325 ;
$this->imgdata[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v79Ehp5Yx/NSq9Jvw+dYwu9YzfZOmbtOmb5myPFG'.
'gqChvcpWteBXvedXxvGcsbtcpb6su8RwzOxNmrhjyvNYwupUjK'.
'ZTr9VXwOyJhmWNAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJTC65k'.
'vQAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_blgr_002.png
//==========================================================
$this->imgdata[4][0]= 325 ;
$this->imgdata[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v79EnpxY8/FS0dJv5+dY7+9Y9vBOubtOur5m8fFG'.
'nKChycpW3uBX5+ZX8e2curtcvrqswsRw7OdNuLZj8/BY6udUpK'.
'ZT1dRX7OtNkrW5AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJgXHeN'.
'wwAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_blue_001.png
//==========================================================
$this->imgdata[5][0]= 325 ;
$this->imgdata[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v79EY55Yi/NSetJvledYiO9YkPZOb7tObr5mkvFG'.
'X6ChrcpWgOBXhedXi/Gcpbtcf76sssRwnOxNcbhjk/NYiepUbK'.
'ZTfdVXh+ynNEzzAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJhStyP'.
'zCAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_oy_007.png
//==========================================================
$this->imgdata[6][0]= 325 ;
$this->imgdata[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v7+ejUTz11jSvVLn02/v1lj21li7q06+r07x2mag'.
'lUbKxKHgy1bnz1fx1Ve7t5y+qlzEwqzs03C4pE3z2WPqz1imml'.
'TVv1Ps01dGRjeyAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJjsGGc'.
'GbAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
//==========================================================
// File: bstar_lred.png
//==========================================================
$this->imgdata[7][0]= 325 ;
$this->imgdata[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'.
'BMVEX///+/v7+eRJPzWN3SUr7nb9TvWNj2WOS7Tqi+TqnxZtyg'.
'Ro/KocPgVsjnV9LxV927nLa+XLTErL7scN24TarzY9/qWNemVJ'.
'jVU8LsV9VCwcc9AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJxi9ZY'.
'GoAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'.
'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'.
'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'.
'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ;
}
}
?>

View File

@ -1,201 +0,0 @@
<?php
//=======================================================================
// File: JPG-CONFIG.INC
// Description: Configuration file for JpGraph library
// Created: 2004-03-27
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpg-config.inc 242 2005-11-20 11:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
//------------------------------------------------------------------------
// Directories for cache and font directory.
//
// CACHE_DIR:
// The full absolute name of the directory to be used to store the
// cached image files. This directory will not be used if the USE_CACHE
// define (further down) is false. If you enable the cache please note that
// this directory MUST be readable and writable for the process running PHP.
// Must end with '/'
//
// TTF_DIR:
// Directory where TTF fonts can be found. Must end with '/'
//
// The default values used if these defines are left commented out are:
//
// UNIX:
// CACHE_DIR /tmp/jpgraph_cache/
// TTF_DIR /usr/X11R6/lib/X11/fonts/truetype/
// MBTTF_DIR /usr/share/fonts/ja/TrueType/
//
// WINDOWS:
// CACHE_DIR $SERVER_TEMP/jpgraph_cache/
// TTF_DIR $SERVER_SYSTEMROOT/fonts/
// MBTTF_DIR $SERVER_SYSTEMROOT/fonts/
//
//------------------------------------------------------------------------
// DEFINE("CACHE_DIR","/tmp/jpgraph_cache/");
// DEFINE("TTF_DIR","/usr/X11R6/lib/X11/fonts/truetype/");
// DEFINE("MBTTF_DIR","/usr/share/fonts/ja/TrueType/");
//-------------------------------------------------------------------------
// Cache directory specification for use with CSIM graphs that are
// using the cache.
// The directory must be the filesysystem name as seen by PHP
// and the 'http' version must be the same directory but as
// seen by the HTTP server relative to the 'htdocs' ddirectory.
// If a relative path is specified it is taken to be relative from where
// the image script is executed.
// Note: The default setting is to create a subdirectory in the
// directory from where the image script is executed and store all files
// there. As ususal this directory must be writeable by the PHP process.
DEFINE("CSIMCACHE_DIR","csimcache/");
DEFINE("CSIMCACHE_HTTP_DIR","csimcache/");
//------------------------------------------------------------------------
// Defines for font setup
//------------------------------------------------------------------------
// Actual name of the TTF file used together with FF_CHINESE aka FF_BIG5
// This is the TTF file being used when the font family is specified as
// either FF_CHINESE or FF_BIG5
DEFINE('CHINESE_TTF_FONT','bkai00mp.ttf');
// Special unicode cyrillic language support
DEFINE("LANGUAGE_CYRILLIC",false);
// If you are setting this config to true the conversion
// will assume that the input text is windows 1251, if
// false it will assume koi8-r
DEFINE("CYRILLIC_FROM_WINDOWS",false);
// Japanese TrueType font used with FF_MINCHO, FF_PMINCHO, FF_GOTHIC, FF_PGOTHIC
DEFINE('MINCHO_TTF_FONT','ipam.ttf');
DEFINE('PMINCHO_TTF_FONT','ipamp.ttf');
DEFINE('GOTHIC_TTF_FONT','ipag.ttf');
DEFINE('PGOTHIC_TTF_FONT','ipagp.ttf');
//------------------------------------------------------------------------
// Various JpGraph Settings. Adjust accordingly to your
// preferences. Note that cache functionality is turned off by
// default (Enable by setting USE_CACHE to true)
//------------------------------------------------------------------------
// Deafult graphic format set to "auto" which will automatically
// choose the best available format in the order png,gif,jpeg
// (The supported format depends on what your PHP installation supports)
DEFINE("DEFAULT_GFORMAT","auto");
// Should the image be a truecolor image?
// Note 1: Has only effect with GD 2.0.1 and above.
// Note 2: GD 2.0.1 + PHP 4.0.6 on Win32 crashes when trying to use
// trucolor.
// Note 3: MUST be enabled to get background images working with GD2
DEFINE('USE_TRUECOLOR',true);
// Specify what version of the GD library is installed.
// If this is set to 'auto' the version will be automatically
// determined.
// However since determining the library takes ~1ms you can also
// manually specify the version if you know what version you have.
// This means that you should
// set this define to true if you have GD 2.x installed to save 1ms.
DEFINE("USE_LIBRARY_GD2",'auto');
// Should the cache be used at all? By setting this to false no
// files will be generated in the cache directory.
// The difference from READ_CACHE being that setting READ_CACHE to
// false will still create the image in the cache directory
// just not use it. By setting USE_CACHE=false no files will even
// be generated in the cache directory.
DEFINE("USE_CACHE",false);
// Should we try to find an image in the cache before generating it?
// Set this define to false to bypass the reading of the cache and always
// regenerate the image. Note that even if reading the cache is
// disabled the cached will still be updated with the newly generated
// image. Set also "USE_CACHE" below.
DEFINE("READ_CACHE",true);
// Determine if the error handler should be image based or purely
// text based. Image based makes it easier since the script will
// always return an image even in case of errors.
DEFINE("USE_IMAGE_ERROR_HANDLER",true);
// Determine if the library should also setup the default PHP
// error handler to generate a graphic error mesage. This is useful
// during development to be able to see the error message as an image
// instead as a "red-cross" in a page where an image is expected.
DEFINE("INSTALL_PHP_ERR_HANDLER",false);
// Should the library examin the global php_errmsg string and convert
// any error in it to a graphical representation. This is handy for the
// occasions when, for example, header files cannot be found and this results
// in the graph not being created and just a "red-cross" image would be seen.
// This should be turned off for a production site.
DEFINE("CATCH_PHPERRMSG",true);
// If the color palette is full should JpGraph try to allocate
// the closest match? If you plan on using background images or
// gradient fills it might be a good idea to enable this.
// If not you will otherwise get an error saying that the color palette is
// exhausted. The drawback of using approximations is that the colors
// might not be exactly what you specified.
// Note1: This does only apply to paletted images, not truecolor
// images since they don't have the limitations of maximum number
// of colors.
DEFINE("USE_APPROX_COLORS",true);
// Should usage of deprecated functions and parameters give a fatal error?
// (Useful to check if code is future proof.)
DEFINE("ERR_DEPRECATED",true);
// Should the time taken to generate each picture be branded to the lower
// left in corner in each generated image? Useful for performace measurements
// generating graphs
DEFINE("BRAND_TIMING",false);
// What format should be used for the timing string?
DEFINE("BRAND_TIME_FORMAT","(%01.3fs)");
//------------------------------------------------------------------------
// The following constants should rarely have to be changed !
//------------------------------------------------------------------------
// What group should the cached file belong to
// (Set to "" will give the default group for the "PHP-user")
// Please note that the Apache user must be a member of the
// specified group since otherwise it is impossible for Apache
// to set the specified group.
DEFINE("CACHE_FILE_GROUP","wwwadmin");
// What permissions should the cached file have
// (Set to "" will give the default persmissions for the "PHP-user")
DEFINE("CACHE_FILE_MOD",0664);
// Decide if we should use the bresenham circle algorithm or the
// built in Arc(). Bresenham gives better visual apperance of circles
// but is more CPU intensive and slower then the built in Arc() function
// in GD. Turned off by default for speed
DEFINE("USE_BRESENHAM",false);
// Special file name to indicate that we only want to calc
// the image map in the call to Graph::Stroke() used
// internally from the GetHTMLCSIM() method.
DEFINE("_CSIM_SPECIALFILE","_csim_special_");
// HTTP GET argument that is used with image map
// to indicate to the script to just generate the image
// and not the full CSIM HTML page.
DEFINE("_CSIM_DISPLAY","_jpg_csimd");
// Special filename for Graph::Stroke(). If this filename is given
// then the image will NOT be streamed to browser of file. Instead the
// Stroke call will return the handler for the created GD image.
DEFINE("_IMG_HANDLER","__handle");
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,206 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_ANTISPAM.PHP
// Description: Genarate anti-spam challenge
// Created: 2004-10-07
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_antispam-digits.php 629 2006-05-26 00:05:28Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class HandDigits {
public $digits = array();
public $iHeight=30, $iWidth=30;
function HandDigits() {
//==========================================================
// d6-small.jpg
//==========================================================
$this->digits['6'][0]= 645 ;
$this->digits['6'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAEBAAMBAAAAAAAAAAAAAAAABgMEBwX/xAAvEAABAwMC'.
'BAQEBwAAAAAAAAABAgMEAAURBiESIjFRBxMUQRUWMmFTYnGRkrHC/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFhEBAQEAAAAA'.
'AAAAAAAAAAAAAAER/9oADAMBAAIRAxEAPwDslwiR3oDku8ONttsAvDiVyMcO/ET7ke5/aoOz6k1Vr5htNjW7a7M1yO3NTQU9JUDu'.
'GgrlSn8xyf6p4gXaHJvNps9/mKZtSkGdMjRwpfqAFBLLACRlZUrJONsI2717No1lbZ10kx7XGnRpKWQ/6GVGMfzEJ5VFIVtsOH6e'.
'wyKVhYsia0y22pLThSkJK1uniVgdThOM0ol+StIUhpopIyCFq3H8aUVCwnG3PGe4Rp6fLXJtMdyM0ojcIWvIz3HFnAPfrWTXb6GN'.
'WaLXDwZjVz8pKEfhuIUFg/bAz9sVJ61nt61mxJFslLtq7e5yPqiBT4UDklKw4MDpt+u+9bFiu9riXNu83R+fcr6tohuQ5HQhmK37'.
'paaC8DruScmg6X8KkjZEhbaB9KEyFYSOw26Uqd+e7Qerl5z74DY/1SomP//Z' ;
//==========================================================
// d2-small.jpg
//==========================================================
$this->digits['2'][0]= 606 ;
$this->digits['2'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEQMBIgACEQEDEQH/xAAYAAEBAQEBAAAAAAAAAAAAAAAFAAQHAv/EACsQAAEDBAEC'.
'BAYDAAAAAAAAAAIBAwQABQYRIRIxQVFhcQcTFSJSU5GU0f/EABcBAAMBAAAAAAAAAAAAAAAAAAECAwT/xAAZEQACAwEAAAAAAAAA'.
'AAAAAAAAARESUUH/2gAMAwEAAhEDEQA/AOqXm/Q8dxmOL4PPSnCSNFixx6nXnkXgRT3Te17JWbGsveueSyLZdbPItNxOKLzTLjou'.
'gYCSoSoY8ISKSbFeUrzkdlnTL1YshskiErkQnFEZaF8kkdBBVdjyi6RNL5+9F486eS/ECVkcBtDt1vZcho5viS8ZCp9C9tAIAm/F'.
'VoPRU+HRtJ5JVRP1kP0PfwP+1VKrHBMliXG4Nw8VgE4xGkuqk2S1wTUNEVdIvgpL9iL6KtNxY7WOwo9tt0RCitj0sR2uCbFPPzH1'.
'7+6rRuSRcljMBMsUy2tky045KOawZk5xtEFBJEROO3hx61kh2rPCIX3MhsyC4QmfTbC6lH8dq5212qwkiG5H6Y/9R2qm+ofxqqsL'.
'DLZ6f//Z' ;
//==========================================================
// d9-small.jpg
//==========================================================
$this->digits['9'][0]= 680 ;
$this->digits['9'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwP/xAArEAABAwMD'.
'AgYBBQAAAAAAAAABAgMEBQYRABIhE1EUIjEzQUIHMlJhcdH/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/xAAYEQEAAwEAAAAAAAAA'.
'AAAAAAAAAREhQf/aAAwDAQACEQMRAD8AkK7brF6X7XpMeGoKhFMLEeT4ZUheEhanF4OcZ2pTgDykk92bZpdCsi7aezLjxkIPUZiV'.
'RSCy8hah7EkZ27yM7V+iscal5bE22Lon1qNDmSKROd8Sl+Ix1lMOlIS4HGgQpbStoUCnlJz8HmsXtW3Lst2rmBAelLMRRekOwnYz'.
'Edls9QKKnOVLyk7UgcbzzrdBthqEJJwZbAI4x1U/7o1TaFa9lG36aXaZTy54VrcXUgrzsGdx+T30aNydweqVw1GS87T6Lb86Q4ha'.
'my/IAYjZBx+snKk99oOQMf1AViE65SY348hzFy6hPKnqtKz7DC1lbqyPrvJKUJ7H+M6Wrt3InP7o1brFNp4bCDGhxGAsqz69VSiQ'.
'ORwBxrrQ7itm1ac7Hp0WoGTIc3PSn0pccdcP2WorycfA1RaRHjxosZqOyhtDTSAhCf2gDAGjVHTd9sKSCumynFEZK1tIJUe58/ro'.
'1V1//9k=' ;
//==========================================================
// d5-small.jpg
//==========================================================
$this->digits['5'][0]= 632 ;
$this->digits['5'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgIFBwT/xAAoEAABAwME'.
'AQQCAwAAAAAAAAABAgMEBQYRABIhIkEUMVFhBxNCgaH/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAv/EABcRAQEBAQAAAAAAAAAAAAAA'.
'AAABEUH/2gAMAwEAAhEDEQA/ANGvW4YVOeiRX5b4mv5Sin05IdlupPKdo/j2SO3+6TbPNQvOsTVz33KRT4csR3YUF7Dsh5OSFvug'.
'kqG4FPBxnjxpvvi4KZb1pTpU+QwxUi2Y7ZIAefUk5ATxnB9/gbtL/wCH1UpuhPUlZlMVaQ0mS8zJjqZOPfc2TwpIUonI9tw40R1r'.
'WNGq/wBdJR1XT3lqHBUnGCfkfWjRWs1ve249erQqQYjOtN1FqPUpCXQ4WIzQSsJwT0UpRwQPG0nzqyuNHobjsl9kBuWqoOoXtT1/'.
'WppZcA8lKRj64HxqU+3KpAr6plElRVKef3S4E0K9O8pLXVzKcqSsJAB9wSAca6bSoNXeuA1+5pEV+SGFNU1iKVFqI0Vdx2AJUeoz'.
'8DGlTDwG3CAf3q/pI0ah6MDhLz6U+EpXwPoaNMU//9k=' ;
//==========================================================
// d1-small.jpg
//==========================================================
$this->digits['1'][0]= 646 ;
$this->digits['1'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEwMBIgACEQEDEQH/xAAZAAADAAMAAAAAAAAAAAAAAAAABQYCBAf/xAApEAACAQMD'.
'AwQBBQAAAAAAAAABAgMEBREABiESMUEHEyJRkSNCYXGB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFxEBAQEBAAAAAAAAAAAA'.
'AAAAAAEREv/aAAwDAQACEQMRAD8A6jdd4WLbstILnc4Uq0VoWpkJknb6IjXLHJUePOlez923fcW4r1SxWlqC2UbdKirQif3Xw3yA'.
'OFAGT09/kO3OmV3a20MFRf6lIYPcpy7yRRAzgxjIy2M8YwcdiBzpX6d22VNvUlTXsFkuwkrKqNSfnK7F8OTzwrAY+l5zoxKskudN'.
'EgQPUT9PBkWF3DH+1GPxo1mLnRoAqF2VRgGOFmX/AAgY/GjRUP6hVMFv2FuFqUvUGrpDFJMBnpdyF5bsAQew7Hxzp6LZNT0yQ1DI'.
'wp0QCFBhD0jCsfLZHxbx5xxpTuvb1+v9PV7Ztk9roLPLCjmSSN3mX5ZwqjCgZX7PfWxDQb2in96pv9qq46aTE0bW4x9ceAWAYPwS'.
'PsYzoixgmheBGjIVcYCnjp/jHjHbRpe1JLn9OnopE/a0ykvjwDx47aNMXqP/2Q==' ;
//==========================================================
// d8-small.jpg
//==========================================================
$this->digits['8'][0]= 694 ;
$this->digits['8'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AFQMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABgcEBf/EACsQAAEDAwMD'.
'AwMFAAAAAAAAAAECAwQFBhEAEiEUMVEHE0EVYYEiIzJCsf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/EABcRAQEBAQAAAAAAAAAA'.
'AAAAAAABERL/2gAMAwEAAhEDEQA/AKL6gVVUa0i1T5QjvTprUJMlxW4R9zgQXe/AH+kaWrntqlWjaq7gpcmotXAw82ht9yY4tch8'.
'uAFC0k7VBXPGMY51ruiaue+bThIj+7NbWqS+7HDxajFf6AlB/k44o8ZOABk4xkL0X0tZiojKrlRuGRJjugqldSlKGf6t7BuUQe3J'.
'44xxxrA1a4KVJipLidri8uLHgqOcfjOPxo0o2hdDvS1CmV2Yl6fS5ioipIQR1CAlKkLKR2UUqAI8g6NRSwuuyHab6s1ufLI/Zai7'.
'UBJOxhTS0+6B32pWSFH4CidOdWU0ukLiN1BLr0zG5Sdm3GRvcPhIT858DvjXNrVsSLnm/VIdTXS6tTnFsxZTSN3jchaTwps+O/z9'.
'tcBVq3hIX0tYqlIiQHdy5CqRHKHXEjAOMgBKjnvyRk4xrQa7OiGt1K5biYZL8SoVEpjOqkFsONtJCNwASeCQrn7aNUKnQYtLp7EC'.
'EylmLHQltptPZKQOBo1FzH//2Q==' ;
//==========================================================
// d4-small.jpg
//==========================================================
$this->digits['4'][0]= 643 ;
$this->digits['4'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABAYHAv/EAC0QAAIBAwQA'.
'BAMJAAAAAAAAAAECAwQFEQAGEiETFDFBUmGBByIjUVNxobHR/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAIB/8QAGBEBAAMBAAAAAAAA'.
'AAAAAAAAAAERIVH/2gAMAwEAAhEDEQA/ANjM00Nxmt1xiWW31CZp5uJwoAAaOQ/n7qfcZHqO5my3q5XX7R6ijiqnNut9u4NyJ4yv'.
'JJyjYr8Xhrn5g599J7x3ulBNU7Zo7dXXXcLQ8kURYi4epYtkALjOePv1nUvbLvV7P3BZm3DR3eh88Kp7pVzBZI6iUhGWRRGWwE44'.
'HX3V+uiL1uHgt+vL/H+aNJQ3CSeCOaFqSaJ1DJKs/TqRkMOvQjvRorHE4pRDLNWLGlRHGUeYIORXs9e5B7OP31E0fmdyb/t0DJ4Q'.
'27bfx3YZzPUIoAAz7IpOD6cuxq0uNumqLfVNDOqXBoZEjnZcqhIPXH4c46+WkdoWOltu3IDDLLLVVR83UVcuPEmmcZZ2/rHoAANG'.
'GI7KIY1ijoLeEQBVCwIoAHpgY6Hy0aZe7mJ2jeHLKcEhusj6aNKgzr//2Q==' ;
//==========================================================
// d7-small.jpg
//==========================================================
$this->digits['7'][0]= 658 ;
$this->digits['7'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgEFBwT/xAAuEAABAwIE'.
'BAQGAwAAAAAAAAABAgMEBREABiExEhMiQSMyUXEHFBclVJFhk9L/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/8QAGREBAQEAAwAA'.
'AAAAAAAAAAAAAAEREiFR/9oADAMBAAIRAxEAPwDXq9mCjZeQ05VZ5ZST4bfEpa3VdglCbqUe+g9MZ5Uq7V8415WXoMSdQ6etgSps'.
'19wpkCMDZKUpv0FZvbi1NzpYasMDLDUbMVXrtQdbeeU23xLWkj5RlLYK0J7anW9gbAjCzkOtsVSUJUdtc6dVZK51UeaFm4LKbhpC'.
'l7EhIFkDW974GbRI2XorUVls1OTdKAOqUpR0Hc3198GITQ6k+hLwrEpoODiDenRfW23bBicg78JXxPpD0mgVOW5PAivNNpahsPW5'.
'8xxQaSVkboQnhsnYm5OHqDGp1IpsalMKjMsMIC3+XZKbJFth62/QOEfMOZqZXp9JcKZTcGmTky3meSi7xQklI81vMR+sXIz/AEgp'.
'Q0qPNu6ea8Q2jqtbp8+2w9h/OKORc/cpHjt1dDSHOtLZ4ekHW23bBjj+o9H/AB539aP94MG0+L//2Q==' ;
//==========================================================
// d3-small.jpg
//==========================================================
$this->digits['3'][0]= 662 ;
$this->digits['3'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwL/xAArEAABBAED'.
'AwMDBQEAAAAAAAABAgMEBREABhIhMUEiMmETFZEHFkJDUdH/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/xAAYEQEBAQEBAAAAAAAA'.
'AAAAAAAAEQExQf/aAAwDAQACEQMRAD8A0vclruBdk3VVLLUNssGRJsZSCtqOjlgJAHvcOD6c4HnOdIbcttw1W5P29cFEhuawqTXS'.
'VsJjnCMBxKkJJx7goAde+ceJfdNxU0UNlyymyXHi6kxWUNl1S3EnkAEIHX2nv86qtTuZr9Q9+1VhRsOoYpYcgSVyAE/TdewkJxnK'.
'sBCjkdPGpnOtFMd3PqsXgfOAgD8Y0aX+11H9rDDjn8lr9yj5J+dGqsqxaw6Cc9cQZU4Sp7zTJsIrKlcUEKwhSin1JABI45GUjqOu'.
'lbOvjbc3Ts9ynjGCy445UuFLYRzbWgrT6fhSCQSMDke+pew2zYVly/d7YchNqkMJZnQpgV9J8IzwWFJyUrAJHYgjvpLbu37G5nR7'.
'vck5C3YRKYEOEVJZj8kjKypXqWvirjk9h+dB9i4faa89TDZUfKlIyT8k+To10a6KTkpcJ/0vL/7o0TS//9k=' ;
}
}
class AntiSpam {
var $iNumber='';
function AntiSpam($aNumber='') {
$this->iNumber = $aNumber;
}
function Rand($aLen) {
$d='';
for($i=0; $i < $aLen; ++$i) {
$d .= rand(1,9);
}
$this->iNumber = $d;
return $d;
}
function Stroke() {
$n=strlen($this->iNumber);
for($i=0; $i < $n; ++$i ) {
if( !is_numeric($this->iNumber[$i]) || $this->iNumber[$i]==0 ) {
return false;
}
}
$dd = new HandDigits();
$n = strlen($this->iNumber);
$img = @imagecreatetruecolor($n*$dd->iWidth, $dd->iHeight);
if( $img < 1 ) {
return false;
}
$start=0;
for($i=0; $i < $n; ++$i ) {
$size = $dd->digits[$this->iNumber[$i]][0];
$dimg = imagecreatefromstring(base64_decode($dd->digits[$this->iNumber[$i]][1]));
imagecopy($img,$dimg,$start,0,0,0,imagesx($dimg), $dd->iHeight);
$start += imagesx($dimg);
}
$resimg = @imagecreatetruecolor($start+4, $dd->iHeight+4);
if( $resimg < 1 ) {
return false;
}
imagecopy($resimg,$img,2,2,0,0,$start, $dd->iHeight);
header("Content-type: image/jpeg");
imagejpeg($resimg);
return true;
}
}
?>

View File

@ -1,612 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_ANTISPAM.PHP
// Description: Genarate anti-spam challenge
// Created: 2004-10-07
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_antispam.php 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
class HandDigits {
public $chars = array();
public $iHeight=30, $iWidth=30;
function HandDigits() {
//==========================================================
// lj-small.jpg
//==========================================================
$this->chars['j'][0]= 658 ;
$this->chars['j'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABUDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUGBAf/xAAsEAACAQMDAwMBCQAAAAAAAAAB'.
'AgMEBREAEjEGIUEUUXGBBxMVIiNSYWKC/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwEC/8QAGhEAAwADAQAAAAAAAAAAAAAAAAECERIh'.
'Mv/aAAwDAQACEQMRAD8A6veK2st8zRWSyV1dUBfvHaGVI4hknsS7AFv4AyM57ayWbqeS+11xtT2etttwo4YqhEqnQs5bcAfyk4AZ'.
'SOeD441TKRTyingUBG4/ah8j684+dSFzh/BvtaslejMUu9DPQTDnLx4lQ/ONw1TGBm0jdRWqguEMghEisWilgDmNs4Ze+MEEEH40'.
'aUVFTa7JeLjRXu4GjhmnNbSfqFQVlA3rkckOjH/Q99Glmkl0C/Q06pvsvT9vttXHDF6T1KrWbs5gRgQJM+FDlQxPhjpF1XcVq+qe'.
'jEoKiOecXBqh2TDDYIXLKuP6549xk8auI6aJqV45oknWdNswkAIkGMYIxjGO2NR1F0LZY5qkWqkS1xrM0M8lMSJpY+TGrnJiQ577'.
'cEgeNHhi7D3qC3UN69M8tIakRhgrh9o748+eNGtcCiKjjpkQKlMTEg3ZwoxtHHtgfTRpYXArvp//2Q==' ;
//==========================================================
// lf-small.jpg
//==========================================================
$this->chars['f'][0]= 633 ;
$this->chars['f'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQFBgcC/8QAKxAAAgEDAwMCBQUAAAAAAAAA'.
'AQIDBBEhAAUGEjFBEyIHFFFhoRUzYnGS/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQP/xAAaEQACAwEBAAAAAAAAAAAAAAAAAQIRMRIh'.
'/9oADAMBAAIRAxEAPwDcnmLoIkiSYsouC3tA++O2lU9WkqVjJ+YdhZLsQI/4/YfQm50kZP0vbmaCSU0SRNIH6sghb9INs3t38dvp'.
'akUuz8x5DwdN5peS1jV1dSipSiVUigIcdQjQ26lIB/c6r3F86SZpE/zCFJaqsihQNhRgdj3Jyfxo0jDSbXHt9Oph9RAoV3qJGltY'.
'HDOxyb/nRpV0D3RXle21m48XraOk3IUSemUaV4g4Zc9ShcDtgff+tQfwvjq34Dtku7buamFqeJKemCCMxKFsEJU+/FrX8d76sEHG'.
'aNItzr4usVNdG3S0rmRYAVwEUmyjyQLZ11x7aF4zs9DQOyzml29I2cLa/pixIHi99DFCtU9dFuLIaijo9qiYPmR2mZmB9thgAHOD'.
'4+mjUrURyrUNMZFEkkIOFuFAbsP9d/OjVIQ6Vh4tP//Z' ;
//==========================================================
// lb-small.jpg
//==========================================================
$this->chars['b'][0]= 645 ;
$this->chars['b'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABUDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAYCAwUH/8QAKxAAAQMDAwMDAwUAAAAAAAAA'.
'AQIDBAAFEQYSIRMxUSJBYQcVI2JxgqHw/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQL/xAAYEQEBAQEBAAAAAAAAAAAAAAAAATERYf/a'.
'AAwDAQACEQMRAD8A6H95mxNYwLXcX+pCuilSLXJ6YSplaUELjqxwe4IJ5PIPamJ2V0bPcS7+NxCX1cHggAnIP+xSd9RyzHh2m7FQ'.
'Q1CvMNQWTjCt+HFD+PB/Y1fI1PL1HFFt0zaGblFdJQ9cJjpZiqPJUlBAKnPcEpGB5NNRKdrOl1NlgiQol4R2w4Sc5VtGf7opZteo'.
'LhdorjUSM5FnQnlR50NeHQysYxtVxlJHIPgjtRRD3xkaghs6juumdHz4+Y7RVPnt59K2mk7W+fcKWsZ7djTXMkW+xMP3GRJjwIEN'.
'HTG/CWx5wPY8AADx2NYk3SL9wukvUjGobnBkORksIbjdMANozgEqSo8qJPGO/wAVO36IsjUmBIfZfuM7epZk3F9UhSSk5O0K9Kcq'.
'8AcU3UzFuhUSBFud6nRXoz96mqmJZWg7m2dqUNhWBwdqQSP1UU5c/FFCn//Z' ;
//==========================================================
// d6-small.jpg
//==========================================================
$this->chars['6'][0]= 645 ;
$this->chars['6'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAEBAAMBAAAAAAAAAAAAAAAABgMEBwX/xAAvEAABAwMC'.
'BAQEBwAAAAAAAAABAgMEAAURBiESIjFRBxMUQRUWMmFTYnGRkrHC/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFhEBAQEAAAAA'.
'AAAAAAAAAAAAAAER/9oADAMBAAIRAxEAPwDslwiR3oDku8ONttsAvDiVyMcO/ET7ke5/aoOz6k1Vr5htNjW7a7M1yO3NTQU9JUDu'.
'GgrlSn8xyf6p4gXaHJvNps9/mKZtSkGdMjRwpfqAFBLLACRlZUrJONsI2717No1lbZ10kx7XGnRpKWQ/6GVGMfzEJ5VFIVtsOH6e'.
'wyKVhYsia0y22pLThSkJK1uniVgdThOM0ol+StIUhpopIyCFq3H8aUVCwnG3PGe4Rp6fLXJtMdyM0ojcIWvIz3HFnAPfrWTXb6GN'.
'WaLXDwZjVz8pKEfhuIUFg/bAz9sVJ61nt61mxJFslLtq7e5yPqiBT4UDklKw4MDpt+u+9bFiu9riXNu83R+fcr6tohuQ5HQhmK37'.
'paaC8DruScmg6X8KkjZEhbaB9KEyFYSOw26Uqd+e7Qerl5z74DY/1SomP//Z' ;
//==========================================================
// lx-small.jpg
//==========================================================
$this->chars['x'][0]= 650 ;
$this->chars['x'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABMDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUHBgj/xAApEAABAwMDAwQCAwAAAAAAAAAB'.
'AgMEBQYRACFBBxIxFCJRgRNxkcHw/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEQH/2gAMAwEA'.
'AhEDEQA/AH9t3pKvO14UykVARa/HfAlxlDKXR24V2p3z7RlPwdtMep91uWdRGHWELjuTFFtLvcC4SNznnH+21O7ttiodOq1BvC0E'.
'p9I0lSX2kgqCSklK+5PKCMAng6zV2XRO6u3lSIURtbDRShltlZHa0tW7q/0MeTwnjxq1Jiw2xc9xTLbhSVU5iaXUFfqFFILgJOCd'.
'9Gt3SXabR6REpkL8yo0RpLCFNx1qBCRjOQMHxo0pEr6o3um2LVYpMEpTVqg25lHn08dfcB9kEgfZ1LIFDuawqZRb7aQlLTzqglsg'.
'9wQdveOEqBIB425xqhQuk8qo9UKlPrlRblw2ZBeCSVKW6CcoSrI2AGOT41SKzT4dYtmdS5bIXDZhNoWgbZJ94x8AYT/GkM03oNUc'.
'uKgwqtTZDTMOU0FttqRkoHggnPkEEHRrkJ6t1SlSHYUOc6zHaWrsbQrATk5/vRqK/9k=' ;
//==========================================================
// d2-small.jpg
//==========================================================
$this->chars['2'][0]= 606 ;
$this->chars['2'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEQMBIgACEQEDEQH/xAAYAAEBAQEBAAAAAAAAAAAAAAAFAAQHAv/EACsQAAEDBAEC'.
'BAYDAAAAAAAAAAIBAwQABQYRIRIxQVFhcQcTFSJSU5GU0f/EABcBAAMBAAAAAAAAAAAAAAAAAAECAwT/xAAZEQACAwEAAAAAAAAA'.
'AAAAAAAAARESUUH/2gAMAwEAAhEDEQA/AOqXm/Q8dxmOL4PPSnCSNFixx6nXnkXgRT3Te17JWbGsveueSyLZdbPItNxOKLzTLjou'.
'gYCSoSoY8ISKSbFeUrzkdlnTL1YshskiErkQnFEZaF8kkdBBVdjyi6RNL5+9F486eS/ECVkcBtDt1vZcho5viS8ZCp9C9tAIAm/F'.
'VoPRU+HRtJ5JVRP1kP0PfwP+1VKrHBMliXG4Nw8VgE4xGkuqk2S1wTUNEVdIvgpL9iL6KtNxY7WOwo9tt0RCitj0sR2uCbFPPzH1'.
'7+6rRuSRcljMBMsUy2tky045KOawZk5xtEFBJEROO3hx61kh2rPCIX3MhsyC4QmfTbC6lH8dq5212qwkiG5H6Y/9R2qm+ofxqqsL'.
'DLZ6f//Z' ;
//==========================================================
// lm-small.jpg
//==========================================================
$this->chars['m'][0]= 649 ;
$this->chars['m'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAcDBAUCBv/EAC0QAAICAQMCBAMJAAAAAAAA'.
'AAECAwQRAAUSBiETMVFhB2KhFSIyQVJxgZHB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAgED/8QAGREBAQEAAwAAAAAAAAAAAAAAAQAR'.
'EiEx/9oADAMBAAIRAxEAPwB0MI2lIdgI0Cly3kFXLEn2zx1FDdp7rbpbjUtRWKio3hyxOGQllJzkegX66rQ2qW87Zuk9S5FNVmru'.
'iywyBhjDKTkeXfSr+GRfYtq2KAO32b1BGxAZu0dyJ2DKPTxY1wPddVszycUq2Golq8jRWbcnJWwCVGMjz+VQP50atxMtm2ZUOY4l'.
'4qfUnBP0x/Z0amy4jJm10Tt2yddWasFmfaRfdrlG3UcgArnxKzJ+Fu4DqCMkcgNem2DoWav8PLfTm+FPEkuSNTnqueS5bnHIv6CG'.
'LNjJwM99bm67NB1Ht89KSxNXnr2hNDbiUc47K4KyD2GQMfmMjUnS+7vuIktTqPCaaWCqAMMojPFyw8hyYMQBnAwNJHYGXPTsW9VN'.
'jg2zf50W9zk524GAEihuz+xbIOD82jW5TkjtRPZkTkJ+4VgDhQfuj/f3OjUxl1f/2Q==' ;
//==========================================================
// lt-small.jpg
//==========================================================
$this->chars['t'][0]= 648 ;
$this->chars['t'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQDBQYH/8QAJxAAAQMDAgYDAQEAAAAAAAAA'.
'AQIDBAUGEQASEyExQVFhIjJxFSP/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAP/xAAZEQADAQEBAAAAAAAAAAAAAAAAAREhMUH/2gAM'.
'AwEAAhEDEQA/AO4BLEiEy7uG4IGxxs5IOOx76wd2XYidSp1HoD70240gcNNPbDyI6wQQpaz8E9MczkdhqtbsKYLieDk6WLKmZmmL'.
'Hk7AHVkbkLI+RQc7uRxgkfr1tx2rGu6VbToLVKkhU+kbugGf9WfaknCk5ycaX0zmaa+3JkqvW/CmzojsB9xoF6OoFK0r6HOcEDI0'.
'aefTuKX5ScMdC14HYq8n12zo1DEUcKTGg1Z+hyBwoPBVIiA/VQyOIgedhUCB4WMfXSV3UufVLcTUIqVf26K6mXDbPVRRzKT54iMg'.
'+zjtq6mtsyJjclxpKlUhSXEbkgkqWnBx4+J5e/zU0pZemPvJJQzEPDfQOrwwFY9AZ5eeYPLV6FwhoFYZuigxpkJeIjqAeIoAk9wA'.
'D46EnuD+6Nc1smDNrTlRkxqtMo1vzKhIdYgU9YDqVpISrLhHxSSd21I0aYyqP//Z' ;
//==========================================================
// li-small.jpg
//==========================================================
$this->chars['i'][0]= 639 ;
$this->chars['i'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABYDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABwAGBP/EACcQAAEEAQMEAgIDAAAAAAAAAAEC'.
'AwQRBQAGEiExQVEHExSBFWFx/8QAFgEBAQEAAAAAAAAAAAAAAAAAAgMB/8QAGBEBAQEBAQAAAAAAAAAAAAAAAAECMRH/2gAMAwEA'.
'AhEDEQA/AE7c+5M9BeRG29t1WUfKFFYW+GvrI7WD3B9g140YD5T36rcErDjbUR6dCBdejsKUpxITXI2FUrooCh70yvxzHyIlMvuK'.
'eVSH7IKEpJoKqu/ahddLryR/aMiO187bsmrWShhp1AZS2XHHrWhNJrzdf7f7GiVcHk3sptmHkJcJ2DIftS2FrKlJPXudWuLGYeQp'.
't2fmEIckqIZaaKuSGG0lQ4gduRoFRHQ9AOgs2lOJbk9aSUlpjGvAWeSVH2VKq/2dFPw3IjyJe8s281ct3I9UoHJXGiQkD2STrSZ7'.
'Yf8AOl7JTdw5eOCz0jw3+LbYCfA9nz71msb8KMxoTGTw+5srjsipAdDqFBQBIuiOl6KrdYyJMyTCshlw2G3Fr/HiNqNNAqJJUoGl'.
'KND+h47km1bZwsvCbYYjycxIyK1qDv2yEi0hQviK8atKDcy9j//Z' ;
//==========================================================
// lp-small.jpg
//==========================================================
$this->chars['p'][0]= 700 ;
$this->chars['p'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGgAAAQUBAAAAAAAAAAAAAAAAAAECBAUGB//EAC8QAAEDAwMCBAMJAAAAAAAA'.
'AAECAwQFESEABhIiMRMVUWEHFEEWIzIzcYGRocH/xAAWAQEBAQAAAAAAAAAAAAAAAAADAgH/xAAcEQACAgIDAAAAAAAAAAAAAAAA'.
'AQIxAxESIUH/2gAMAwEAAhEDEQA/AOh703xG21DMeOyqoVNDjSzERiwU6Ep5qtZNycA97HTF13d33KWtmlt9xwkLl1NkXVxIuQgK'.
'wLj+hqBvel0qmbR8GnR22nJNZiLeeKr8nDIT1OLJucX+uPbWom7iocRpafOac5MX1ALltp/Cbi+cJH++utdh+WVNL3PNdNYpdWgx'.
'Y0qmLZSrwJJcQoOJ5XKlJFu4HbJOjVbt+V5nu7eopNRivqcdhK+bFnWwA1Y2AOcgjvj9dGlxy0g5y0xd+hNXoG24C4obizq3HZUh'.
'YHqtRHD06bG/8a0MbbG1mqekxaBSGmgkrcdcitlLfrckZIz7DUatbeFak0tyRLUwzT5vmiGm0cufEkFBJItfkD+59tKmiO12atFa'.
'eQukO3ejUxgENqTcfnE5WbkHiOnJ76N2IqI1DibabptS+zkZhtp90F2Y0S026EkAFK/qL46cXv65NVZDfxHmVCK4DE2/RX/lRFbA'.
'C5LwAyq2EtpHZI7mxPYDRqoctdESimz/2Q==' ;
//==========================================================
// le-small.jpg
//==========================================================
$this->chars['e'][0]= 700 ;
$this->chars['e'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABgDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAYEBQcB/8QAKhAAAQMCBAUEAwEAAAAAAAAA'.
'AgEDBAURAAYSIQciMTJBE0JRYRQVFoH/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAgED/8QAGREAAwEBAQAAAAAAAAAAAAAAAAERAjFB'.
'/9oADAMBAAIRAxEAPwDTszvhEYCoS80BTm2bCjQRwdAzVe2yopkpJtpRUVfjEIc4V2oMerByg5Ji30oMyS3GeMunK0upfnu09MdJ'.
'p2scTmWnnGfx6HThktgLfKj7xEOqyr7QBbL41LhBzpxbcOru0LKDLdSnOHoaltNqSC4qWL0x9xbJYum69caczSaHmGmTmpDUYn4l'.
'UiqjkynzAVtwV23Ud+X4Ibpa2DCPkjhfUaRO/p8yzpb+YHhUmhbev6ZEll1lvqK3jt2XrbBgp6HVwsK3THpfEubGSoOUyFMpbJmL'.
'Deh6SgOGKti57EuY6l62JMWdJy7k3hg1LkOozEbVm7suQSkTiKtkEfP1pH664Za/QItccgI4bseTHdNxiXHLQ8yVl7V32XyioqL5'.
'TGc1ng6eYs0idczXUZscBBABWgEhEtfKNuUezwPnBhEuj8X2M21z9BR6NUX211Kk/UKKAjuhkPhL7XVf8vtgw7UPJlEyrDWFSYLb'.
'LBNF6qrzG6t0spEu6+fpL7YMXhUndp//2Q==' ;
//==========================================================
// la-small.jpg
//==========================================================
$this->chars['a'][0]= 730 ;
$this->chars['a'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABoDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAABgMEBwX/xAAvEAABAwIFAQcCBwAAAAAAAAAB'.
'AgMEBREAEiExQQYHFBUiUXGBE2EyQkNSgpHh/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAMBAv/EABkRAAMBAQEAAAAAAAAAAAAAAAAB'.
'IQIRMf/aAAwDAQACEQMRAD8AfdQ1pxjqZMSn0mRUZRYDaklJCE3OawO2ttTxY4hl07qFMVs1Ku02kpPnRGhsAqz8W9T9wDjozq6o'.
'Q1lDrcZLGVcmUoZg0obpufxK3Ftt9ccqB1GgBcmLSqtVEqOZcr6ARm/kbXHt7DEtc7WTJKTJqEWvRKfLqL9QplSjuPtGVYOJKBrm'.
't+U+n94WGStZzNypmRWqckUKTbixy6jAfxPxHtCgKqFNlU5huK6pLMndSlegG4J45N8aKmTMKQRBsCNMzwB+RbHWHGEAZlPZX2hx'.
'qZIC34ygZoYUbB50JSkFXFhZR9BrpheR4fIbQ6gvurJ7q02bIQTuAOAN8x40HAxRr3TrNRpBmSHVt1KMlTyJTCsqkKAPlSf28W+c'.
'UGaD1c9HSR1HFUh9tJU45EBcAtcC9+P9wqbg8IAto9o81yputrVGpiUkgHKkqUTZI32+cKm1z1tIUgPBBAKQ4UBQH3uL3xmXSXep'.
'HVDtXStE5K5jlPU7PF3Q41+okJFkjgC+3OuNSYiSzHaLtRcW4UDMpLYSCbakDW3thhum5p//2Q==' ;
//==========================================================
// d9-small.jpg
//==========================================================
$this->chars['9'][0]= 680 ;
$this->chars['9'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwP/xAArEAABAwMD'.
'AgYBBQAAAAAAAAABAgMEBQYRABIhE1EUIjEzQUIHMlJhcdH/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/xAAYEQEAAwEAAAAAAAAA'.
'AAAAAAAAAREhQf/aAAwDAQACEQMRAD8AkK7brF6X7XpMeGoKhFMLEeT4ZUheEhanF4OcZ2pTgDykk92bZpdCsi7aezLjxkIPUZiV'.
'RSCy8hah7EkZ27yM7V+iscal5bE22Lon1qNDmSKROd8Sl+Ix1lMOlIS4HGgQpbStoUCnlJz8HmsXtW3Lst2rmBAelLMRRekOwnYz'.
'Edls9QKKnOVLyk7UgcbzzrdBthqEJJwZbAI4x1U/7o1TaFa9lG36aXaZTy54VrcXUgrzsGdx+T30aNydweqVw1GS87T6Lb86Q4ha'.
'my/IAYjZBx+snKk99oOQMf1AViE65SY348hzFy6hPKnqtKz7DC1lbqyPrvJKUJ7H+M6Wrt3InP7o1brFNp4bCDGhxGAsqz69VSiQ'.
'ORwBxrrQ7itm1ac7Hp0WoGTIc3PSn0pccdcP2WorycfA1RaRHjxosZqOyhtDTSAhCf2gDAGjVHTd9sKSCumynFEZK1tIJUe58/ro'.
'1V1//9k=' ;
//==========================================================
// d5-small.jpg
//==========================================================
$this->chars['5'][0]= 632 ;
$this->chars['5'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgIFBwT/xAAoEAABAwME'.
'AQQCAwAAAAAAAAABAgMEBQYRABIhIkEUMVFhBxNCgaH/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAv/EABcRAQEBAQAAAAAAAAAAAAAA'.
'AAABEUH/2gAMAwEAAhEDEQA/ANGvW4YVOeiRX5b4mv5Sin05IdlupPKdo/j2SO3+6TbPNQvOsTVz33KRT4csR3YUF7Dsh5OSFvug'.
'kqG4FPBxnjxpvvi4KZb1pTpU+QwxUi2Y7ZIAefUk5ATxnB9/gbtL/wCH1UpuhPUlZlMVaQ0mS8zJjqZOPfc2TwpIUonI9tw40R1r'.
'WNGq/wBdJR1XT3lqHBUnGCfkfWjRWs1ve249erQqQYjOtN1FqPUpCXQ4WIzQSsJwT0UpRwQPG0nzqyuNHobjsl9kBuWqoOoXtT1/'.
'WppZcA8lKRj64HxqU+3KpAr6plElRVKef3S4E0K9O8pLXVzKcqSsJAB9wSAca6bSoNXeuA1+5pEV+SGFNU1iKVFqI0Vdx2AJUeoz'.
'8DGlTDwG3CAf3q/pI0ah6MDhLz6U+EpXwPoaNMU//9k=' ;
//==========================================================
// d1-small.jpg
//==========================================================
$this->chars['1'][0]= 646 ;
$this->chars['1'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEwMBIgACEQEDEQH/xAAZAAADAAMAAAAAAAAAAAAAAAAABQYCBAf/xAApEAACAQMD'.
'AwQBBQAAAAAAAAABAgMEBREABiESMUEHEyJRkSNCYXGB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFxEBAQEBAAAAAAAAAAAA'.
'AAAAAAEREv/aAAwDAQACEQMRAD8A6jdd4WLbstILnc4Uq0VoWpkJknb6IjXLHJUePOlez923fcW4r1SxWlqC2UbdKirQif3Xw3yA'.
'OFAGT09/kO3OmV3a20MFRf6lIYPcpy7yRRAzgxjIy2M8YwcdiBzpX6d22VNvUlTXsFkuwkrKqNSfnK7F8OTzwrAY+l5zoxKskudN'.
'EgQPUT9PBkWF3DH+1GPxo1mLnRoAqF2VRgGOFmX/AAgY/GjRUP6hVMFv2FuFqUvUGrpDFJMBnpdyF5bsAQew7Hxzp6LZNT0yQ1DI'.
'wp0QCFBhD0jCsfLZHxbx5xxpTuvb1+v9PV7Ztk9roLPLCjmSSN3mX5ZwqjCgZX7PfWxDQb2in96pv9qq46aTE0bW4x9ceAWAYPwS'.
'PsYzoixgmheBGjIVcYCnjp/jHjHbRpe1JLn9OnopE/a0ykvjwDx47aNMXqP/2Q==' ;
//==========================================================
// ll-small.jpg
//==========================================================
$this->chars['l'][0]= 626 ;
$this->chars['l'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYEBQf/xAArEAACAQIFAwIGAwAAAAAAAAAB'.
'AgMEEQAFBhIhFEFREzEHFSIyYcFxgZH/xAAXAQEAAwAAAAAAAAAAAAAAAAACAAED/8QAGhEAAwEAAwAAAAAAAAAAAAAAAAECMREh'.
'Qf/aAAwDAQACEQMRAD8A15Zfm1VURj1Fp5AqLKv3OARcL4W5Nzx+MLWjdRz5hqXU6TSb6OCr6WghiQbrJ91gOTy1yT5xZ55myZFk'.
'Gb5ozX6Ondm28XYqpQDwu7jEH4c5S2UaDy4xxrLmlUDWzk8XaQ3O49hbj+RiB85HNg8Ee3aqwIqhDuux7G/HHbvzgxEqaWOvy09R'.
'O0o3hjdQoUji20g+fY3wYSM6pJ4Ylr7V+Zz5PSaezHTlTRNWzxySSxt6q1MSkH6AOT2Fu3Aw7RfF/T9DEkLUeawuF2mKSgdWQj2/'.
'q3+fnDZDlqRZzQGaOGcpTOaeR1u8R+ncN3gj94so2jNWHeMNNKzorEX2qp9v3imNPoRE1zpjUtZ09HJmYq5lury0benZeTww23t3'.
'Ivgw+T0yRRyyxIqNfkLcA8jt7YMKcBWn/9k=' ;
//==========================================================
// ls-small.jpg
//==========================================================
$this->chars['s'][0]= 701 ;
$this->chars['s'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAMCBAUGB//EACwQAAEEAQIFAgUFAAAAAAAA'.
'AAECAwQFEQAGEhMUITEiYQcjQVFxFRZCUoH/xAAWAQEBAQAAAAAAAAAAAAAAAAADAgH/xAAZEQADAQEBAAAAAAAAAAAAAAAAAQIR'.
'EiH/2gAMAwEAAhEDEQA/APWZMhmFXSJU+SGmWFiQtAWMJQAnJUr8Z+w/OuQk71uZnMsqnbjy9s8st9UMCQ6kZJdZaIHEkZ/JHceN'.
'N3HtizuY1JLrG48yLBSC9UTFKQiY4nACir+wAOOMEe2rm2bTbzlqtE1MyBuZAPybpw85KSfDRJ4Cg+Pl/wC61hJeGjV31VuuKqwr'.
'LGU+whZZK+Rw+oYJAyj3GjS4dZFpZVkqPLktdfMXNcaU2kBC1BIITkdx6c599GlnvPAa3TL2vNvU76n0063acr3YSLCEjpUpUQtW'.
'Dhf14SMEnOc57aZ8Tegm7dbrEQGZt1PeTDgc1PEW3FeXAvyAkZVkeMDOm2G3f3O7Cl/qEuqkQg4lp6CRxraWfUlRUD24kZA741Ko'.
'2k1HvlT3ri2sLOCgtsyJz6XEtBwZPAgJAGQMHUNPWKqWItsqh0UCFVyLeKhyLHQ2TMdHNVj+RKlAnJyfto1FW2ahgjrq6LYTFjjf'.
'lymUOLdWfJyoHA+gA7AAAaNPE3ysJdLT/9k=' ;
//==========================================================
// lh-small.jpg
//==========================================================
$this->chars['h'][0]= 677 ;
$this->chars['h'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABUDASIAAhEBAxEB/8QAGgAAAQUBAAAAAAAAAAAAAAAAAAIDBAUGB//EACwQAAIBAwMCBQIHAAAAAAAA'.
'AAECAwQFEQAGEiExExQiQVEVggcyU2GRocH/xAAXAQADAQAAAAAAAAAAAAAAAAAAAwQB/8QAGhEBAQEAAwEAAAAAAAAAAAAAAQAC'.
'AyEyMf/aAAwDAQACEQMRAD8A6DZb95q9bmpK6ieOCzNHJTxmE+NMhQ5fr1fLq3Ejvkak2e7ipiFsqb3R0m4qkPPJRiRXenU9VjKE'.
'5JVcA9R7nWc3/BUbfoKTdO3VRXhpjbZ2D8Rwk6RyZH6chB+46m7i2hDYtgA2ePlV2VkuKysoLzzRnlIScZJZeeevvjtrX7LK2rp7'.
'tTwwJ9WjhILDrTKnIdMEDl2+P80aVdJZb1QW+vgqENLPH4sBCDLIwUgnOf4GjVvDnLgUk79T81voqjb8NnuUx8pVRCiEaYUSuynl'.
'jHU9mOfnOoOx6hqz8PrbNdfEkMUXg1LSM3rKOUywJ7YAJ1ZTWmSpvdvlaVTDSUzJAhH5ZJBgv0x2RSAPlz21WXqoet3ba9nuW8n4'.
'Jr6qTPqnUNxSM/f6mPvxA9zqJnExTbR+h0nkhVu1uE8j0UBRQ9PGxBKFjnkAScdsDp10a0lc7z0tI7Y5YYN+5GAf7GjVXF4Icj3f'.
'/9k=' ;
//==========================================================
// ld-small.jpg
//==========================================================
$this->chars['d'][0]= 681 ;
$this->chars['d'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQFBgH/xAAsEAABAwMEAAQFBQAAAAAAAAAB'.
'AgMEBQYRABIhMQcTI0EUMlFhkRgicaGx/8QAFgEBAQEAAAAAAAAAAAAAAAAAAgEA/8QAGBEBAQEBAQAAAAAAAAAAAAAAAAECETH/'.
'2gAMAwEAAhEDEQA/ALUhp6h3W/X63UlypbhCY0WMjLqGzwDtPCfv/WtealNpVInuVBBqCogcdbU36YUkAkJWVHG8YPXBxxzxqPcN'.
'YtWyWnIlUeW05VEOAvrCnnSkftK1H5lKJPHsMDoDUWq+KdrSbIqsalVsImiEtLUZ2MU71bcYJWkhZ/36ayLHhi/IXZVOmzKqp5uU'.
'688hTyjuGVEFJKvoQesD86NL2jGZp1EoLDSmk+ZAQ8d7oPzp3YGesFWMfxo1YGvSzLsT9QExVX8phTlMaFOExAJIBGQjJwCcL+/e'.
'rd+W7GuO0Kw05CQ6+ww69Gfdb2kFIKk7DgEkjgnr86rXRa9HuyP8LV4SH0sIBbWFFDiFEgDaocgdkjo8ccay0qw7ut5nyrcviQqC'.
'slsRKo0HwlODkBRzxj2AGoXTtpzIdQ8MbffUChz4NCPRaClAo9Mn6c7T3o13wytmo0K05VIqkiPJbizFiMWs4CTgnIIHOST796NL'.
'Ia1JX//Z' ;
//==========================================================
// d8-small.jpg
//==========================================================
$this->chars['8'][0]= 694 ;
$this->chars['8'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AFQMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABgcEBf/EACsQAAEDAwMD'.
'AwMFAAAAAAAAAAECAwQFBhEAEiEUMVEHE0EVYYEiIzJCsf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/EABcRAQEBAQAAAAAAAAAA'.
'AAAAAAABERL/2gAMAwEAAhEDEQA/AKL6gVVUa0i1T5QjvTprUJMlxW4R9zgQXe/AH+kaWrntqlWjaq7gpcmotXAw82ht9yY4tch8'.
'uAFC0k7VBXPGMY51ruiaue+bThIj+7NbWqS+7HDxajFf6AlB/k44o8ZOABk4xkL0X0tZiojKrlRuGRJjugqldSlKGf6t7BuUQe3J'.
'44xxxrA1a4KVJipLidri8uLHgqOcfjOPxo0o2hdDvS1CmV2Yl6fS5ioipIQR1CAlKkLKR2UUqAI8g6NRSwuuyHab6s1ufLI/Zai7'.
'UBJOxhTS0+6B32pWSFH4CidOdWU0ukLiN1BLr0zG5Sdm3GRvcPhIT858DvjXNrVsSLnm/VIdTXS6tTnFsxZTSN3jchaTwps+O/z9'.
'tcBVq3hIX0tYqlIiQHdy5CqRHKHXEjAOMgBKjnvyRk4xrQa7OiGt1K5biYZL8SoVEpjOqkFsONtJCNwASeCQrn7aNUKnQYtLp7EC'.
'EylmLHQltptPZKQOBo1FzH//2Q==' ;
//==========================================================
// lz-small.jpg
//==========================================================
$this->chars['z'][0]= 690 ;
$this->chars['z'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABYDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABgAHA//EACsQAAEDAwQBAwIHAAAAAAAAAAEC'.
'AwQFESEABhIxBxMiQVFxCCM0UmGRof/EABYBAQEBAAAAAAAAAAAAAAAAAAECAP/EABgRAAMBAQAAAAAAAAAAAAAAAAABEVEC/9oA'.
'DAMBAAIRAxEAPwBTWfLu1KXXZDbM4uewNvLajlwhaCbBAwDe5uehYd3xm6t6bi3jvulwqc7KgxXZZeYQLNLeF73WRg4HEdgfzrSa'.
'P45pNEkznITDc9ypLShtyWhJDJyXC2qxJHZvjoZOjyVv1v8AESt6FFS4ijxvTLbawEApSccrYHJf0+OtJMQ2rNXk7GZMufJgJjTH'.
'Un9M4qzxT7hyCiThIyRnPXWrRvyLElVBUF6vlhl0lwRYCFKcQhAtyWpVhyWTx+w++rUvp4EWjOvbniUOnVatcS43BYDbJSPZyIBw'.
'ejclIx+3Wa+J63T6DQanuGszI0eZVJJV60p0Jum5GEi6le7l0PjvSjyRsaTvJqI1BqhhR46ksuMrQVJcUSEoUbHNr/7o7C8L7eiz'.
'4lLlyJk2cEqW+6V+m0AE9ISLnsj5+O9UhsFK92bZZqb9SRu9p2c4A0OCEqDbYAJSlJwAVZv3fBvbFrg/462btlhuS1RG5nL8pYkq'.
'KrnsKH06I/rVrQKkf//Z' ;
//==========================================================
// d4-small.jpg
//==========================================================
$this->chars['4'][0]= 643 ;
$this->chars['4'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABAYHAv/EAC0QAAIBAwQA'.
'BAMJAAAAAAAAAAECAwQFEQAGEiETFDFBUmGBByIjUVNxobHR/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAIB/8QAGBEBAAMBAAAAAAAA'.
'AAAAAAAAAAERIVH/2gAMAwEAAhEDEQA/ANjM00Nxmt1xiWW31CZp5uJwoAAaOQ/n7qfcZHqO5my3q5XX7R6ijiqnNut9u4NyJ4yv'.
'JJyjYr8Xhrn5g599J7x3ulBNU7Zo7dXXXcLQ8kURYi4epYtkALjOePv1nUvbLvV7P3BZm3DR3eh88Kp7pVzBZI6iUhGWRRGWwE44'.
'HX3V+uiL1uHgt+vL/H+aNJQ3CSeCOaFqSaJ1DJKs/TqRkMOvQjvRorHE4pRDLNWLGlRHGUeYIORXs9e5B7OP31E0fmdyb/t0DJ4Q'.
'27bfx3YZzPUIoAAz7IpOD6cuxq0uNumqLfVNDOqXBoZEjnZcqhIPXH4c46+WkdoWOltu3IDDLLLVVR83UVcuPEmmcZZ2/rHoAANG'.
'GI7KIY1ijoLeEQBVCwIoAHpgY6Hy0aZe7mJ2jeHLKcEhusj6aNKgzr//2Q==' ;
//==========================================================
// lv-small.jpg
//==========================================================
$this->chars['v'][0]= 648 ;
$this->chars['v'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQDBQYH/8QAKBAAAQQBAwMEAgMAAAAAAAAA'.
'AQIDBBEFAAYhEzFBEhQiYQdRFTKB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAERIf/aAAwD'.
'AQACEQMRAD8A6Ngt1SZ4yrYgrecgTFsFJA9aGwAUrUaF2D2Avjzq6CIjiBPkB9bwQVIkIYIDae/wq+P9N+dY4SGMf+Txlev7KBmY'.
'PoadKRy4zxSgRxaTwO/x09u7KPYnasmHjlsyFZZXt4K23ezjvBpNGgLUrvXfVZyLLbWambiwEbKvvxYAkeotNlIJW2FEJWb7WBda'.
'NSQI0fHYyJjkrjKRDZQwnpQ1vgBIr+w8+a+9GocZr8iKkuY1eXhsKH8U8iZE9BHz6ZHUc48UfSPqzqH3kfeO9kTTDQYGGietpTaO'.
'shyW6AocpHNIrv8AvWzk9BUSdPdYS4BcRlomkhIV6KP0VE39V+tU2wdlRMHtZUB8NuTQ+51X27+Kr46ZPIAFV540D8zeLsJ5LMHa'.
'ubmMBCVJdjx0pRyLoWR4I8aNIQ8BvZMNtMTeUcsptKfc4tC1gAkCyFC+K0aJtf/Z' ;
//==========================================================
// lk-small.jpg
//==========================================================
$this->chars['k'][0]= 680 ;
$this->chars['k'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABUDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAUGBAMH/8QALhAAAQMDAwIEBAcAAAAAAAAA'.
'AQIDBAUREgAGITFBEyIyYQcVUYEUIzNicZHx/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwEE/8QAGxEAAwACAwAAAAAAAAAAAAAAAAEC'.
'AxESMeH/2gAMAwEAAhEDEQA/APVK/V36dU6NSJDTT8esPLiqfK8S2cCoeTkKvZQ6jm2ldSqKqbu+OgMOvSX3m4UBrLnDlbqiefKl'.
'Nzz2x1m+IwNP27CkJQ7JkR6rCkMJbP5jp8S2CPfkgD6H+dJ6Ca0nerr+64rTNSqMYrg+C9mmOwhVpDfsuxSbi97DmybaoZeQ5jTl'.
'PEp18JTIfeW3kq3ly4H26aNZqvTWZsjFcZTsVtSg0G8Rio+vr2vb7g6NLPRnuXy8F+8kl+obUh4KXJdqSJJQnohlkZqJPYBXh3P+'.
'a4b5Hyp6k1bO7sOotPyXkj9NlwFl0ewstJA9ifrqkVSmET4csoS7UTHXFQ+6SQlskKUMb/tH9ddLVUmS7DqdBqD7U6OsqfS46jzl'.
'hQ5bXb1K9Scuybdxo2OTu92dwSZkWn0Sb8viQWyn8Qq5D6ifSLd0BIv7q0arTBRSKPToMZbi2GWylsvLK148Wue/XRrRjxOpT2R2'.
'k9aP/9k=' ;
//==========================================================
// lr-small.jpg
//==========================================================
$this->chars['r'][0]= 681 ;
$this->chars['r'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABYDASIAAhEBAxEB/8QAGgAAAgIDAAAAAAAAAAAAAAAAAAYCBQMEB//EAC4QAAICAQIFAgMJAQAAAAAA'.
'AAECAwQRBQYAEiExQQdRFGFxEyIyM0JSYoGC8P/EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/EABcRAQEBAQAAAAAAAAAAAAAAAAAB'.
'EUH/2gAMAwEAAhEDEQA/AOs0ZdETU54Gt1INSmlPJEsyo7J+jlXPUYBPY9c+eE/dO9tY0a7ren6BVrW7VJTZtW5kZkjXkBSIKveQ'.
'gHp0AAJ4w+q2hVdT2Md0h46+saS4mr3EUK0gWTAB+vQj2PboeL/ZVOqmhaZVjkFmxdC6tctt3tM2G5/7bAx4C4+qxiWwd3prWzKe'.
'r3IBAth5OYxozKsgc8y4GTgnJB9uncdTi6tXq2140rRVM13JMEMAVAg7sMdBjJB/18uDgRO9R2Oo6FX2vShkFzURFUq1whIj+8DI'.
'7EdAFjXv7MeNb0kuStsFEmIaajZaos2fy2Q4VGH7SGxn+Rzw9yMLOm/FzRhZazmOTkP4grYyD3B8j2PTyeFfZ+z7G3BeSS8lmprl'.
'2K2qcnK0Z5S8gPjrgAY8cNEWmq7u23pEos6/Zji+Kd0rLLGWwseA3joeZj/w4OET1g0vlmrWV+ydFnkUxSgsvM4V+YYIwfHz6cHB'.
'ZeKZ1//Z' ;
//==========================================================
// lg-small.jpg
//==========================================================
$this->chars['g'][0]= 655 ;
$this->chars['g'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQCBQYH/8QAJxAAAQQBAwQCAgMAAAAAAAAA'.
'AQIDBBEFAAYhBxIxQRNhcYEiQlH/xAAYAQACAwAAAAAAAAAAAAAAAAACAwABBP/EABkRAAMBAQEAAAAAAAAAAAAAAAABAhEhIv/a'.
'AAwDAQACEQMRAD8AayO4t6bq3hmMHtxyLi4OKeKH5jyASiiQCCQeTRNAeB61FrBb+jTGpLO+BMW24EFMhkhpQru8m7B/H70x09Yi'.
'q3nv/vLfwpnJ7UNkqSRbngf2ofWkpXV7brymC2malLfagurjW0aHk89xPJ9cX9aprURHWbYEaMHHEBfwpv8AnXPk+/8AdGqGJOxO'.
'4YbOSxK4y4boIStUWysgkEmxY54r60aOI8oTV9MHtjJwunPUbO46WWo0HLlD8KY4goboFVoquOVEVwLT963WdnxYfT6ZJyz0JvHm'.
'KvtaSkW4tYNVSqKiTwB+fw5n9sY/cuOXCzDDcluyW3Ckd7V+0n0eNZTH9DdouFalHIOJBUhtDki0pNV3UALo81ehG6IdKjPZ6d47'.
'4ywltanVJvuJI+RQs/sHRqy2r003JhsImEc/CUyhxRZBjKV2oJ8eRXNmufPnRo1WIz3DdNn/2Q==' ;
//==========================================================
// lc-small.jpg
//==========================================================
$this->chars['c'][0]= 629 ;
$this->chars['c'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAUGBwID/8QALRAAAgICAQIEBAYDAAAAAAAA'.
'AQIDBAURACExBhIiQRMVUWEHMkJScYFykaH/xAAWAQEBAQAAAAAAAAAAAAAAAAABAgP/xAAXEQEBAQEAAAAAAAAAAAAAAAAAATER'.
'/9oADAMBAAIRAxEAPwDcoGkmiT4Q8kWvzuPU38D2/v8A1zwrCFayq1qTaFk2H7aJHt05MeMvENzC4upDWkjW9kJXiricAJCigvJN'.
'IB1IVQT5frrv24twPgunk6a288crbklUSJNNdnSTZ2STHHqOP/Eb17njdZtAoqwEvrEiGVyG117/AG6HhyV8H1sljMldoxXTksGC'.
'zV7M0oaWGQOVeGQ92I6EMR22D11w4LmEPjaOL51iL8ssc9Z69zHtZkYCGGeQK0ez2UEoU39wCeX1S/LLiEt+mPSbMLxsGVv2kEjR'.
'305xkaEV/GTULMUT1LD/AAGh8gIZS2jv+vpybb8NMIb0dVLWYWgiiU0vmMphOj6V0TvQI3rfsON1E6dYjGtisa0F1mAWR2NhG0WZ'.
'3Ls3TqNs5Hc9h23w49NWL9K+Q/VD5T/zhwPH/9k=' ;
//==========================================================
// d7-small.jpg
//==========================================================
$this->chars['7'][0]= 658 ;
$this->chars['7'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgEFBwT/xAAuEAABAwIE'.
'BAQGAwAAAAAAAAABAgMEBREABiExEhMiQSMyUXEHFBclVJFhk9L/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/8QAGREBAQEAAwAA'.
'AAAAAAAAAAAAAAEREiFR/9oADAMBAAIRAxEAPwDXq9mCjZeQ05VZ5ZST4bfEpa3VdglCbqUe+g9MZ5Uq7V8415WXoMSdQ6etgSps'.
'19wpkCMDZKUpv0FZvbi1NzpYasMDLDUbMVXrtQdbeeU23xLWkj5RlLYK0J7anW9gbAjCzkOtsVSUJUdtc6dVZK51UeaFm4LKbhpC'.
'l7EhIFkDW974GbRI2XorUVls1OTdKAOqUpR0Hc3198GITQ6k+hLwrEpoODiDenRfW23bBicg78JXxPpD0mgVOW5PAivNNpahsPW5'.
'8xxQaSVkboQnhsnYm5OHqDGp1IpsalMKjMsMIC3+XZKbJFth62/QOEfMOZqZXp9JcKZTcGmTky3meSi7xQklI81vMR+sXIz/AEgp'.
'Q0qPNu6ea8Q2jqtbp8+2w9h/OKORc/cpHjt1dDSHOtLZ4ekHW23bBjj+o9H/AB539aP94MG0+L//2Q==' ;
//==========================================================
// ly-small.jpg
//==========================================================
$this->chars['y'][0]= 672 ;
$this->chars['y'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQGBQf/xAArEAABAwMEAQIFBQAAAAAAAAAB'.
'AgMEBREhAAYSEzEHIhQkQVGxQmFxgaH/xAAWAQEBAQAAAAAAAAAAAAAAAAADAQL/xAAeEQEAAgEEAwAAAAAAAAAAAAABABECAxIh'.
'MUGR8P/aAAwDAQACEQMRAD8Ar3tys07dVHohemz5dWQ7fk91MsA3IIRY8rkKFySceTqw3JVV0KhyKw+0C1CQp9aUOFSiAk4AIAvn'.
'76xtz0ioVvbcJ6msx2JtOfZmw1PKI5LQcJNh7UqBKcn6+NRfqPu6s1fYc6GxSJsRfWDUVSGA22ygEckJWSexRNgOP0udXzDKOJ0I'.
'yo62mHm25Sy80l1Z4lSgpQvZRGLgWwPGjTjbchyLH+Ejx22EtJSgO8kki3kADA/nOjWjGzv73CyQZjUWNVp7bNSrj7qJDqflqUlQ'.
'DMds24l3HvcNr3Pi9gME6T9WWVsemdYWswwC2lPta4m5WMA3OdUExCmozUJD6g84ntMjrHIFBTdQz5yLDx/WDNytpwW6nAkViqVe'.
'uvmXdlme6n4dCwlRBKEgA2tj99QG7Ilncp5QqpU31PMsJ6x7A32f6SPxo0hPVCD45oVyKf0MtgeT97/nRrO7UOCFla3tn//Z' ;
//==========================================================
// d3-small.jpg
//==========================================================
$this->chars['3'][0]= 662 ;
$this->chars['3'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'.
'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwL/xAArEAABBAED'.
'AwMDBQEAAAAAAAABAgMEBREABhIhMUEiMmETFZEHFkJDUdH/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/xAAYEQEBAQEBAAAAAAAA'.
'AAAAAAAAEQExQf/aAAwDAQACEQMRAD8A0vclruBdk3VVLLUNssGRJsZSCtqOjlgJAHvcOD6c4HnOdIbcttw1W5P29cFEhuawqTXS'.
'VsJjnCMBxKkJJx7goAde+ceJfdNxU0UNlyymyXHi6kxWUNl1S3EnkAEIHX2nv86qtTuZr9Q9+1VhRsOoYpYcgSVyAE/TdewkJxnK'.
'sBCjkdPGpnOtFMd3PqsXgfOAgD8Y0aX+11H9rDDjn8lr9yj5J+dGqsqxaw6Cc9cQZU4Sp7zTJsIrKlcUEKwhSin1JABI45GUjqOu'.
'lbOvjbc3Ts9ynjGCy445UuFLYRzbWgrT6fhSCQSMDke+pew2zYVly/d7YchNqkMJZnQpgV9J8IzwWFJyUrAJHYgjvpLbu37G5nR7'.
'vck5C3YRKYEOEVJZj8kjKypXqWvirjk9h+dB9i4faa89TDZUfKlIyT8k+To10a6KTkpcJ/0vL/7o0TS//9k=' ;
//==========================================================
// ln-small.jpg
//==========================================================
$this->chars['n'][0]= 643 ;
$this->chars['n'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGwAAAgEFAAAAAAAAAAAAAAAAAAYCAQMEBQf/xAAtEAACAQMCBAUCBwAAAAAA'.
'AAABAgMEBREAIQYSE0EHIjFRcWGRIzIzQoGCwf/EABYBAQEBAAAAAAAAAAAAAAAAAAMEAP/EABkRAQEBAQEBAAAAAAAAAAAAAAEA'.
'AhEhUf/aAAwDAQACEQMRAD8A6FR3p7v4oV9rlkMQsjL00RyOss0KkFxnDcrc2PbI1NOJKyTjW+W5OmKeA0UEJx5meRZS2/8AUfbS'.
'LVGS1+K16vCzfiR3GmoqqXGyxz06hWPsFlVMfOmq1iNvE69KjBYo3oJMZ3GKeYYPxg/fW+xzZX1FLQyxwSTcpWNceu4G3+aNSmpY'.
'qmQzzwh2k8yhv2r2H23/AJ0aoy+EWh7I1ntacR3PxDtEzhjWy0wkkIwYmanU5GO6sNh7rrU8AVdTceNbhDXxNHUQvS0tZ3DzwxVA'.
'fB7hj59/XJ08cPWaKj4gvlwSQiG7dCboqvLy9NOmQT9SM7ayJrBa6K5V91hjlWorp4JGUOAglRSiMMDb82/vgaBGTpVvtNUVtyJg'.
'5+WNAh5ZCu/r2+dGrgq0pi0DhmlRsSSAfqMd+b6ZyNu3po1Rk1yNBe3/2Q==' ;
//==========================================================
// lu-small.jpg
//==========================================================
$this->chars['u'][0]= 671 ;
$this->chars['u'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAYDBAUH/8QAJRAAAQQBAwQDAQEAAAAAAAAA'.
'AQIDBBEFAAYhBxMxYRJBURSB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAQAD/8QAGhEBAQEAAwEAAAAAAAAAAAAAAQARITFBAv/aAAwD'.
'AQACEQMRAD8A6dLkQmJzu3WVtHIqjf0duKFNuBr5UTQ45F1R8/XI1PMmsYoJyjhS9iI7BKHeKjkXZVXqhyLHP+rrHeR1pZlx1W1M'.
'wTiW0ukkrS28nn5fV2SPPFfurHUKQhzYG7pLYKEfyBhaSOS7dG/YCki/uvWn3LPDOJrwa4kyEzOYeakqkpC3Hk0bNePQHgDRpchY'.
'leIZwzUWauKtuPctTSUlCAUmrBHIKuAPV/ujQsmHdm7hya43UbbD3ZVElOQJsdTS6IQaQUqBHCk8E2Pocgam6oYwObHy0Zm0oi45'.
'T1KBPdpV2f0pom/1Ws7cmPazu98Ltvcq3VzRHfehz8a4pirFEKRZo8eQT+eCdWYfS/b+WYnxpbuVcDRMdHcyTqg2fiAfiLoi+Rf+'.
'jT7Xc74HtOYnHyUOh8yWUvKeHhy0CiPVUAPoDRrm+OeznTva6lzsyMjCYbbaiNJjJSWElagD5tRpNUSALFeNGoOCH7Bv/9k=' ;
//==========================================================
// lw-small.jpg
//==========================================================
$this->chars['w'][0]= 673 ;
$this->chars['w'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABcDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYDBAX/xAAtEAACAQMDAgMHBQAAAAAAAAAB'.
'AgMEBREABhIhMRMUQRUiIzJRYZEWNIGx0f/EABYBAQEBAAAAAAAAAAAAAAAAAAABA//EABoRAAICAwAAAAAAAAAAAAAAAAABERIh'.
'MVH/2gAMAwEAAhEDEQA/AHXbV13ZLu6t2/uaa1JijWopVp4XUTKSAXRyc+6ehBGeoPbTSlwpql0K3GneqpZViqUhI5JzGMEZJGeh'.
'GlXfaFILDf7FQzXC426rDLTojs8sLqVkXBGcfKf40twWbdWzZY75R0s90ul3jPtKjVMJDNn4DDp8iEhW+wJ1WZG2KWt3Lv26U1tv'.
'92o7PaYkgYUbqVepYlmUBlIwqnB++O2jTDt/bBtth9jcpvEWNGqalZQryTlmeR8jPct6+mNGmRC4a1U13htzVFItB5nA/cyOUVfp'.
'7oz/ALqitJulYJKuqvFsppHALLFb3cp9FBaXr+O51bq0q6i38KK5PDVAAxSzU6SIpz3Kjjn8jUFoS7uFmut1gq17xLFQ+DxOccj8'.
'Rsn+tVpiyJnqv09YfOXu5AycgZZQEhBZjgDBOOgwO/po0sttWHdNzqLruioa4UwmdaC3kYp4IwSvJlBHKQ4OSe3po0qxM6P/2Q==' ;
//==========================================================
// lq-small.jpg
//==========================================================
$this->chars['q'][0]= 671 ;
$this->chars['q'][1]=
'/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'.
'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'.
'MjIyMjIyMjL/wAARCAAeABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAcDBAUG/8QAKRAAAQQBBAICAQQDAAAAAAAA'.
'AQIDBBEFAAYSIQcxIlETCBQVgSNBYf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oADAMB'.
'AAIRAxEAPwDT3H5Qz+O3LN2vtrF/y86NYLzzVlAABJITQPv2a/17vXMboz3lDEYWPuafNx7CFrS03+2jpK2bs0CUkUa7pRvrUu63'.
'sr438yv7pLEo4XIK5Kcji0uJUkckm+uQUOVH6GsnyJv7A5vaJwuFdkONLmolgONFH4vioKRXYqyCADXvRMh0yspmZ4jyIEtDTK47'.
'aiA0lQUopBJBI/7X9aNT7amRo228e3a31iO3yUzCcdSPiKAIFdCho0TIswZ7GQlO/hlRxBooih1YXzAoKUkX0LPEBX110dJ7zbuv'.
'AORpO04cIpmxH23FSEIRwKuNnsdk0o31702XhFMKbuRUZJWP8LTQ6HBCuIB+iVWSR2BXuqK93/hDlvGzEphmG3Ml5JpDi1I7TzNA'.
'BYFlPafY+/7LBiv1CYDH4iFDOGySlMR22lFP4wCUpANfL11o1r4bxXlWMNEaE/bqlIbCFl/ANPK5Do/M0VDr2Rf3o0TX/9k=' ;
}
}
class AntiSpam {
private $iData='';
private $iDD=null;
function AntiSpam($aData='') {
$this->iData = $aData;
$this->iDD = new HandDigits();
}
function Rand($aLen) {
$d='';
for($i=0; $i < $aLen; ++$i) {
if( rand(0,9) < 6 ) {
// Digits
$d .= chr( ord('1') + rand(0,8) );
}
else {
// Letters
do {
$offset = rand(0,25);
} while ( $offset==14 );
$d .= chr( ord('a') + $offset );
}
}
$this->iData = $d;
return $d;
}
function Stroke() {
$n=strlen($this->iData);
if( $n==0 ) {
return false;
}
for($i=0; $i < $n; ++$i ) {
if( $this->iData[$i]==='0' || strtolower($this->iData[$i])==='o') {
return false;
}
}
$img = @imagecreatetruecolor($n*$this->iDD->iWidth, $this->iDD->iHeight);
if( $img < 1 ) {
return false;
}
$start=0;
for($i=0; $i < $n; ++$i ) {
$dimg = imagecreatefromstring(base64_decode($this->iDD->chars[strtolower($this->iData[$i])][1]));
imagecopy($img,$dimg,$start,0,0,0,imagesx($dimg), $this->iDD->iHeight);
$start += imagesx($dimg);
}
$resimg = @imagecreatetruecolor($start+4, $this->iDD->iHeight+4);
if( $resimg < 1 ) {
return false;
}
imagecopy($resimg,$img,2,2,0,0,$start, $this->iDD->iHeight);
header("Content-type: image/jpeg");
imagejpeg($resimg);
return true;
}
}
?>

View File

@ -1,964 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_BAR.PHP
// Description: Bar plot extension for JpGraph
// Created: 2001-01-08
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_bar.php 634 2006-05-26 00:59:09Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
require_once('jpgraph_plotband.php');
// Pattern for Bars
DEFINE('PATTERN_DIAG1',1);
DEFINE('PATTERN_DIAG2',2);
DEFINE('PATTERN_DIAG3',3);
DEFINE('PATTERN_DIAG4',4);
DEFINE('PATTERN_CROSS1',5);
DEFINE('PATTERN_CROSS2',6);
DEFINE('PATTERN_CROSS3',7);
DEFINE('PATTERN_CROSS4',8);
DEFINE('PATTERN_STRIPE1',9);
DEFINE('PATTERN_STRIPE2',10);
//===================================================
// CLASS BarPlot
// Description: Main code to produce a bar plot
//===================================================
class BarPlot extends Plot {
public $fill=false,$fill_color="lightblue"; // Default is to fill with light blue
public $iPattern=-1,$iPatternDensity=80,$iPatternColor='black';
public $valuepos='top';
public $grad=false,$grad_style=1;
public $grad_fromcolor=array(50,50,200),$grad_tocolor=array(255,255,255);
protected $width=0.4; // in percent of major ticks
protected $abswidth=-1; // Width in absolute pixels
protected $ybase=0; // Bars start at 0
protected $align="center";
protected $bar_shadow=false;
protected $bar_shadow_color="black";
protected $bar_shadow_hsize=3,$bar_shadow_vsize=3;
//---------------
// CONSTRUCTOR
function BarPlot($datay,$datax=false) {
$this->Plot($datay,$datax);
++$this->numpoints;
}
//---------------
// PUBLIC METHODS
// Set a drop shadow for the bar (or rather an "up-right" shadow)
function SetShadow($color="black",$hsize=3,$vsize=3,$show=true) {
$this->bar_shadow=$show;
$this->bar_shadow_color=$color;
$this->bar_shadow_vsize=$vsize;
$this->bar_shadow_hsize=$hsize;
// Adjust the value margin to compensate for shadow
$this->value->margin += $vsize;
}
// DEPRECATED use SetYBase instead
function SetYMin($aYStartValue) {
//die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead.");
$this->ybase=$aYStartValue;
}
// Specify the base value for the bars
function SetYBase($aYStartValue) {
$this->ybase=$aYStartValue;
}
function Legend($graph) {
if( $this->grad && $this->legend!="" && !$this->fill ) {
$color=array($this->grad_fromcolor,$this->grad_tocolor);
// In order to differentiate between gradients and cooors specified as an RGB triple
$graph->legend->Add($this->legend,$color,"",-$this->grad_style,
$this->legendcsimtarget,$this->legendcsimalt);
}
elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) {
if( is_array($this->iPattern) ) {
$p1 = $this->iPattern[0];
$p2 = $this->iPatternColor[0];
$p3 = $this->iPatternDensity[0];
}
else {
$p1 = $this->iPattern;
$p2 = $this->iPatternColor;
$p3 = $this->iPatternDensity;
}
$color = array($p1,$p2,$p3,$this->fill_color);
// A kludge: Too mark that we add a pattern we use a type value of < 100
$graph->legend->Add($this->legend,$color,"",-101,
$this->legendcsimtarget,$this->legendcsimalt);
}
elseif( $this->fill_color && $this->legend!="" ) {
if( is_array($this->fill_color) ) {
$graph->legend->Add($this->legend,$this->fill_color[0],"",0,
$this->legendcsimtarget,$this->legendcsimalt);
}
else {
$graph->legend->Add($this->legend,$this->fill_color,"",0,
$this->legendcsimtarget,$this->legendcsimalt);
}
}
}
// Gets called before any axis are stroked
function PreStrokeAdjust($graph) {
parent::PreStrokeAdjust($graph);
// If we are using a log Y-scale we want the base to be at the
// minimum Y-value unless the user have specifically set some other
// value than the default.
if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 )
$this->ybase = $graph->yaxis->scale->GetMinVal();
// For a "text" X-axis scale we will adjust the
// display of the bars a little bit.
if( substr($graph->axtype,0,3)=="tex" ) {
// Position the ticks between the bars
$graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0);
// Center the bars
if( $this->abswidth > -1 ) {
$graph->SetTextScaleAbsCenterOff($this->abswidth);
}
else {
if( $this->align == "center" )
$graph->SetTextScaleOff(0.5-$this->width/2);
elseif( $this->align == "right" )
$graph->SetTextScaleOff(1-$this->width);
}
}
elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) {
// We only set an absolute width for linear and int scale
// for text scale the width will be set to a fraction of
// the majstep width.
if( $this->abswidth == -1 ) {
// Not set
// set width to a visuable sensible default
$this->abswidth = $graph->img->plotwidth/(2*count($this->coords[0]));
}
}
}
function Min() {
$m = parent::Min();
if( $m[1] >= $this->ybase )
$m[1] = $this->ybase;
return $m;
}
function Max() {
$m = parent::Max();
if( $m[1] <= $this->ybase )
$m[1] = $this->ybase;
return $m;
}
// Specify width as fractions of the major stepo size
function SetWidth($aWidth) {
if( $aWidth > 1 ) {
// Interpret this as absolute width
$this->abswidth=$aWidth;
}
else
$this->width=$aWidth;
}
// Specify width in absolute pixels. If specified this
// overrides SetWidth()
function SetAbsWidth($aWidth) {
$this->abswidth=$aWidth;
}
function SetAlign($aAlign) {
$this->align=$aAlign;
}
function SetNoFill() {
$this->grad = false;
$this->fill_color=false;
$this->fill=false;
}
function SetFillColor($aColor) {
$this->fill = true ;
$this->fill_color=$aColor;
}
function SetFillGradient($from_color,$to_color,$style) {
$this->grad=true;
$this->grad_fromcolor=$from_color;
$this->grad_tocolor=$to_color;
$this->grad_style=$style;
}
function SetValuePos($aPos) {
$this->valuepos = $aPos;
}
function SetPattern($aPattern, $aColor='black'){
if( is_array($aPattern) ) {
$n = count($aPattern);
$this->iPattern = array();
$this->iPatternDensity = array();
if( is_array($aColor) ) {
$this->iPatternColor = array();
if( count($aColor) != $n ) {
JpGraphError::Raise('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()');
}
}
else
$this->iPatternColor = $aColor;
for( $i=0; $i < $n; ++$i ) {
$this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]);
if( is_array($aColor) ) {
$this->iPatternColor[$i] = $aColor[$i];
}
}
}
else {
$this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity);
$this->iPatternColor = $aColor;
}
}
function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){
switch( $aPattern ) {
case PATTERN_DIAG1:
$aPatternValue= 1;
$aDensity = 90;
break;
case PATTERN_DIAG2:
$aPatternValue= 1;
$aDensity = 75;
break;
case PATTERN_DIAG3:
$aPatternValue= 2;
$aDensity = 90;
break;
case PATTERN_DIAG4:
$aPatternValue= 2;
$aDensity = 75;
break;
case PATTERN_CROSS1:
$aPatternValue= 8;
$aDensity = 90;
break;
case PATTERN_CROSS2:
$aPatternValue= 8;
$aDensity = 78;
break;
case PATTERN_CROSS3:
$aPatternValue= 8;
$aDensity = 65;
break;
case PATTERN_CROSS4:
$aPatternValue= 7;
$aDensity = 90;
break;
case PATTERN_STRIPE1:
$aPatternValue= 5;
$aDensity = 90;
break;
case PATTERN_STRIPE2:
$aPatternValue= 5;
$aDensity = 75;
break;
default:
JpGraphError::Raise('Unknown pattern specified in call to BarPlot::SetPattern()');
}
}
function Stroke($img,$xscale,$yscale) {
$numpoints = count($this->coords[0]);
if( isset($this->coords[1]) ) {
if( count($this->coords[1])!=$numpoints )
JpGraphError::Raise("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints");
else
$exist_x = true;
}
else
$exist_x = false;
$numbars=count($this->coords[0]);
// Use GetMinVal() instead of scale[0] directly since in the case
// of log scale we get a correct value. Log scales will have negative
// values for values < 1 while still not representing negative numbers.
if( $yscale->GetMinVal() >= 0 )
$zp=$yscale->scale_abs[0];
else {
$zp=$yscale->Translate(0);
}
if( $this->abswidth > -1 ) {
$abswidth=$this->abswidth;
}
else
$abswidth=round($this->width*$xscale->scale_factor,0);
// Count pontetial pattern array to avoid doing the count for each iteration
if( is_array($this->iPattern) ) {
$np = count($this->iPattern);
}
for($i=0; $i < $numbars; ++$i) {
// If value is NULL, or 0 then don't draw a bar at all
if ($this->coords[0][$i] === null ||
$this->coords[0][$i] === '' ||
$this->coords[0][$i] === 0 ) continue;
if( $exist_x ) $x=$this->coords[1][$i];
else $x=$i;
$x=$xscale->Translate($x);
// Comment Note: This confuses the positioning when using acc together with
// grouped bars. Workaround for fixing #191
/*
if( !$xscale->textscale ) {
if($this->align=="center")
$x -= $abswidth/2;
elseif($this->align=="right")
$x -= $abswidth;
}
*/
// Stroke fill color and fill gradient
$pts=array(
$x,$zp,
$x,$yscale->Translate($this->coords[0][$i]),
$x+$abswidth,$yscale->Translate($this->coords[0][$i]),
$x+$abswidth,$zp);
if( $this->grad ) {
$grad = new Gradient($img);
$grad->FilledRectangle($pts[2],$pts[3],
$pts[6],$pts[7],
$this->grad_fromcolor,$this->grad_tocolor,$this->grad_style);
}
elseif( !empty($this->fill_color) ) {
if(is_array($this->fill_color)) {
$img->PushColor($this->fill_color[$i % count($this->fill_color)]);
} else {
$img->PushColor($this->fill_color);
}
$img->FilledPolygon($pts);
$img->PopColor();
}
// Remember value of this bar
$val=$this->coords[0][$i];
if( !empty($val) && !is_numeric($val) ) {
JpGraphError::Raise('All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\'');
}
// Determine the shadow
if( $this->bar_shadow && $val != 0) {
$ssh = $this->bar_shadow_hsize;
$ssv = $this->bar_shadow_vsize;
// Create points to create a "upper-right" shadow
if( $val > 0 ) {
$sp[0]=$pts[6]; $sp[1]=$pts[7];
$sp[2]=$pts[4]; $sp[3]=$pts[5];
$sp[4]=$pts[2]; $sp[5]=$pts[3];
$sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv;
$sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv;
$sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv;
}
elseif( $val < 0 ) {
$sp[0]=$pts[4]; $sp[1]=$pts[5];
$sp[2]=$pts[6]; $sp[3]=$pts[7];
$sp[4]=$pts[0]; $sp[5]=$pts[1];
$sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv;
$sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv;
$sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv;
}
if( is_array($this->bar_shadow_color) ) {
$numcolors = count($this->bar_shadow_color);
if( $numcolors == 0 ) {
JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.');
}
$img->PushColor($this->bar_shadow_color[$i % $numcolors]);
}
else {
$img->PushColor($this->bar_shadow_color);
}
$img->FilledPolygon($sp);
$img->PopColor();
}
// Stroke the pattern
if( is_array($this->iPattern) ) {
$f = new RectPatternFactory();
if( is_array($this->iPatternColor) ) {
$pcolor = $this->iPatternColor[$i % $np];
}
else
$pcolor = $this->iPatternColor;
$prect = $f->Create($this->iPattern[$i % $np],$pcolor,1);
$prect->SetDensity($this->iPatternDensity[$i % $np]);
if( $val < 0 ) {
$rx = $pts[0];
$ry = $pts[1];
}
else {
$rx = $pts[2];
$ry = $pts[3];
}
$width = abs($pts[4]-$pts[0])+1;
$height = abs($pts[1]-$pts[3])+1;
$prect->SetPos(new Rectangle($rx,$ry,$width,$height));
$prect->Stroke($img);
}
else {
if( $this->iPattern > -1 ) {
$f = new RectPatternFactory();
$prect = $f->Create($this->iPattern,$this->iPatternColor,1);
$prect->SetDensity($this->iPatternDensity);
if( $val < 0 ) {
$rx = $pts[0];
$ry = $pts[1];
}
else {
$rx = $pts[2];
$ry = $pts[3];
}
$width = abs($pts[4]-$pts[0])+1;
$height = abs($pts[1]-$pts[3])+1;
$prect->SetPos(new Rectangle($rx,$ry,$width,$height));
$prect->Stroke($img);
}
}
// Stroke the outline of the bar
if( is_array($this->color) )
$img->SetColor($this->color[$i % count($this->color)]);
else
$img->SetColor($this->color);
$pts[] = $pts[0];
$pts[] = $pts[1];
if( $this->weight > 0 ) {
$img->SetLineWeight($this->weight);
$img->Polygon($pts);
}
// Determine how to best position the values of the individual bars
$x=$pts[2]+($pts[4]-$pts[2])/2;
if( $this->valuepos=='top' ) {
$y=$pts[3];
if( $img->a === 90 ) {
if( $val < 0 )
$this->value->SetAlign('right','center');
else
$this->value->SetAlign('left','center');
}
$this->value->Stroke($img,$val,$x,$y);
}
elseif( $this->valuepos=='max' ) {
$y=$pts[3];
if( $img->a === 90 ) {
if( $val < 0 )
$this->value->SetAlign('left','center');
else
$this->value->SetAlign('right','center');
}
else {
$this->value->SetAlign('center','top');
}
$this->value->SetMargin(-3);
$this->value->Stroke($img,$val,$x,$y);
}
elseif( $this->valuepos=='center' ) {
$y = ($pts[3] + $pts[1])/2;
$this->value->SetAlign('center','center');
$this->value->SetMargin(0);
$this->value->Stroke($img,$val,$x,$y);
}
elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) {
$y=$pts[1];
if( $img->a === 90 ) {
if( $val < 0 )
$this->value->SetAlign('right','center');
else
$this->value->SetAlign('left','center');
}
$this->value->SetMargin(3);
$this->value->Stroke($img,$val,$x,$y);
}
else {
JpGraphError::Raise('Unknown position for values on bars :'.$this->valuepos);
}
// Create the client side image map
$rpts = $img->ArrRotate($pts);
$csimcoord=round($rpts[0]).", ".round($rpts[1]);
for( $j=1; $j < 4; ++$j){
$csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]);
}
if( !empty($this->csimtargets[$i]) ) {
$this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" ';
$this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\"";
$sval='';
if( !empty($this->csimalts[$i]) ) {
$sval=sprintf($this->csimalts[$i],$this->coords[0][$i]);
$this->csimareas .= " title=\"$sval\" ";
}
$this->csimareas .= " alt=\"$sval\" />\n";
}
}
return true;
}
} // Class
//===================================================
// CLASS GroupBarPlot
// Description: Produce grouped bar plots
//===================================================
class GroupBarPlot extends BarPlot {
private $plots, $nbrplots=0;
//---------------
// CONSTRUCTOR
function GroupBarPlot($plots) {
$this->width=0.7;
$this->plots = $plots;
$this->nbrplots = count($plots);
if( $this->nbrplots < 1 ) {
JpGraphError::Raise('Cannot create GroupBarPlot from empty plot array.');
}
for($i=0; $i < $this->nbrplots; ++$i ) {
if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
JpGraphError::Raise("Group bar plot element nbr $i is undefined or empty.");
}
}
$this->numpoints = $plots[0]->numpoints;
$this->width=0.7;
}
//---------------
// PUBLIC METHODS
function Legend($graph) {
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
$c = get_class($this->plots[$i]);
if( !($this->plots[$i] instanceof BarPlot) ) {
JpGraphError::Raise('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')');
}
$this->plots[$i]->DoLegend($graph);
}
}
function Min() {
list($xmin,$ymin) = $this->plots[0]->Min();
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
list($xm,$ym) = $this->plots[$i]->Min();
$xmin = max($xmin,$xm);
$ymin = min($ymin,$ym);
}
return array($xmin,$ymin);
}
function Max() {
list($xmax,$ymax) = $this->plots[0]->Max();
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
list($xm,$ym) = $this->plots[$i]->Max();
$xmax = max($xmax,$xm);
$ymax = max($ymax,$ym);
}
return array($xmax,$ymax);
}
function GetCSIMareas() {
$n = count($this->plots);
$csimareas='';
for($i=0; $i < $n; ++$i) {
$csimareas .= $this->plots[$i]->csimareas;
}
return $csimareas;
}
// Stroke all the bars next to each other
function Stroke($img,$xscale,$yscale) {
$tmp=$xscale->off;
$n = count($this->plots);
$subwidth = $this->width/$this->nbrplots ;
for( $i=0; $i < $n; ++$i ) {
$this->plots[$i]->ymin=$this->ybase;
$this->plots[$i]->SetWidth($subwidth);
// If the client have used SetTextTickInterval() then
// major_step will be > 1 and the positioning will fail.
// If we assume it is always one the positioning will work
// fine with a text scale but this will not work with
// arbitrary linear scale
$xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth);
$this->plots[$i]->Stroke($img,$xscale,$yscale);
}
$xscale->off=$tmp;
}
} // Class
//===================================================
// CLASS AccBarPlot
// Description: Produce accumulated bar plots
//===================================================
class AccBarPlot extends BarPlot {
private $plots=null,$nbrplots=0;
//---------------
// CONSTRUCTOR
function AccBarPlot($plots) {
$this->plots = $plots;
$this->nbrplots = count($plots);
if( $this->nbrplots < 1 ) {
JpGraphError::Raise('Cannot create AccBarPlot from empty plot array.');
}
for($i=0; $i < $this->nbrplots; ++$i ) {
if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
JpGraphError::Raise("Acc bar plot element nbr $i is undefined or empty.");
}
}
$this->numpoints = $plots[0]->numpoints;
$this->value = new DisplayValue();
}
//---------------
// PUBLIC METHODS
function Legend($graph) {
$n = count($this->plots);
for( $i=$n-1; $i >= 0; --$i ) {
$c = get_class($this->plots[$i]);
if( !($this->plots[$i] instanceof BarPlot) ) {
JpGraphError::Raise('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')');
}
$this->plots[$i]->DoLegend($graph);
}
}
function Max() {
list($xmax) = $this->plots[0]->Max();
$nmax=0;
for($i=0; $i < count($this->plots); ++$i) {
$n = count($this->plots[$i]->coords[0]);
$nmax = max($nmax,$n);
list($x) = $this->plots[$i]->Max();
$xmax = max($xmax,$x);
}
for( $i = 0; $i < $nmax; $i++ ) {
// Get y-value for bar $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots max y-value since that
// would in most cases give to large y-value.
$y=0;
if( !isset($this->plots[0]->coords[0][$i]) ) {
JpGraphError::RaiseL(2014);
}
if( $this->plots[0]->coords[0][$i] > 0 )
$y=$this->plots[0]->coords[0][$i];
for( $j = 1; $j < $this->nbrplots; $j++ ) {
if( !isset($this->plots[$j]->coords[0][$i]) ) {
JpGraphError::RaiseL(2014);
}
if( $this->plots[$j]->coords[0][$i] > 0 )
$y += $this->plots[$j]->coords[0][$i];
}
$ymax[$i] = $y;
}
$ymax = max($ymax);
// Bar always start at baseline
if( $ymax <= $this->ybase )
$ymax = $this->ybase;
return array($xmax,$ymax);
}
function Min() {
$nmax=0;
list($xmin,$ysetmin) = $this->plots[0]->Min();
for($i=0; $i < count($this->plots); ++$i) {
$n = count($this->plots[$i]->coords[0]);
$nmax = max($nmax,$n);
list($x,$y) = $this->plots[$i]->Min();
$xmin = Min($xmin,$x);
$ysetmin = Min($y,$ysetmin);
}
for( $i = 0; $i < $nmax; $i++ ) {
// Get y-value for bar $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots max y-value since that
// would in most cases give to large y-value.
$y=0;
if( $this->plots[0]->coords[0][$i] < 0 )
$y=$this->plots[0]->coords[0][$i];
for( $j = 1; $j < $this->nbrplots; $j++ ) {
if( $this->plots[$j]->coords[0][$i] < 0 )
$y += $this->plots[ $j ]->coords[0][$i];
}
$ymin[$i] = $y;
}
$ymin = Min($ysetmin,Min($ymin));
// Bar always start at baseline
if( $ymin >= $this->ybase )
$ymin = $this->ybase;
return array($xmin,$ymin);
}
// Stroke acc bar plot
function Stroke($img,$xscale,$yscale) {
$pattern=NULL;
$img->SetLineWeight($this->weight);
for($i=0; $i < $this->numpoints-1; $i++) {
$accy = 0;
$accy_neg = 0;
for($j=0; $j < $this->nbrplots; ++$j ) {
$img->SetColor($this->plots[$j]->color);
if ( $this->plots[$j]->coords[0][$i] >= 0) {
$yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
$accyt=$yscale->Translate($accy);
$accy+=$this->plots[$j]->coords[0][$i];
}
else {
//if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) {
$yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
$accyt=$yscale->Translate($accy_neg);
$accy_neg+=$this->plots[$j]->coords[0][$i];
}
$xt=$xscale->Translate($i);
if( $this->abswidth > -1 )
$abswidth=$this->abswidth;
else
$abswidth=round($this->width*$xscale->scale_factor,0);
$pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt);
if( $this->bar_shadow ) {
$ssh = $this->bar_shadow_hsize;
$ssv = $this->bar_shadow_vsize;
// We must also differ if we are a positive or negative bar.
if( $j === 0 ) {
// This gets extra complicated since we have to
// see all plots to see if we are negative. It could
// for example be that all plots are 0 until the very
// last one. We therefore need to save the initial setup
// for both the negative and positive case
// In case the final bar is positive
$sp[0]=$pts[6]+1; $sp[1]=$pts[7];
$sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv;
// In case the final bar is negative
$nsp[0]=$pts[0]; $nsp[1]=$pts[1];
$nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv;
$nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv;
$nsp[10]=$pts[6]+1; $nsp[11]=$pts[7];
}
if( $j === $this->nbrplots-1 ) {
// If this is the last plot of the bar and
// the total value is larger than 0 then we
// add the shadow.
if( is_array($this->bar_shadow_color) ) {
$numcolors = count($this->bar_shadow_color);
if( $numcolors == 0 ) {
JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.');
}
$img->PushColor($this->bar_shadow_color[$i % $numcolors]);
}
else {
$img->PushColor($this->bar_shadow_color);
}
if( $accy > 0 ) {
$sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv;
$sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv;
$sp[8]=$pts[2]; $sp[9]=$pts[3]-1;
$sp[10]=$pts[4]+1; $sp[11]=$pts[5];
$img->FilledPolygon($sp,4);
}
elseif( $accy_neg < 0 ) {
$nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv;
$nsp[8]=$pts[4]+1; $nsp[9]=$pts[5];
$img->FilledPolygon($nsp,4);
}
$img->PopColor();
}
}
// If value is NULL or 0, then don't draw a bar at all
if ($this->plots[$j]->coords[0][$i] == 0 ) continue;
if( $this->plots[$j]->grad ) {
$grad = new Gradient($img);
$grad->FilledRectangle(
$pts[2],$pts[3],
$pts[6],$pts[7],
$this->plots[$j]->grad_fromcolor,
$this->plots[$j]->grad_tocolor,
$this->plots[$j]->grad_style);
} else {
if (is_array($this->plots[$j]->fill_color) ) {
$numcolors = count($this->plots[$j]->fill_color);
$img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]);
}
else {
$img->SetColor($this->plots[$j]->fill_color);
}
$img->FilledPolygon($pts);
$img->SetColor($this->plots[$j]->color);
}
// Stroke the pattern
if( $this->plots[$j]->iPattern > -1 ) {
if( $pattern===NULL )
$pattern = new RectPatternFactory();
$prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1);
$prect->SetDensity($this->plots[$j]->iPatternDensity);
if( $this->plots[$j]->coords[0][$i] < 0 ) {
$rx = $pts[0];
$ry = $pts[1];
}
else {
$rx = $pts[2];
$ry = $pts[3];
}
$width = abs($pts[4]-$pts[0])+1;
$height = abs($pts[1]-$pts[3])+1;
$prect->SetPos(new Rectangle($rx,$ry,$width,$height));
$prect->Stroke($img);
}
// CSIM array
if( $i < count($this->plots[$j]->csimtargets) ) {
// Create the client side image map
$rpts = $img->ArrRotate($pts);
$csimcoord=round($rpts[0]).", ".round($rpts[1]);
for( $k=1; $k < 4; ++$k){
$csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]);
}
if( ! empty($this->plots[$j]->csimtargets[$i]) ) {
$this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" ';
$this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\"";
$sval='';
if( !empty($this->plots[$j]->csimalts[$i]) ) {
$sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]);
$this->csimareas .= " title=\"$sval\" ";
}
$this->csimareas .= " alt=\"$sval\" />\n";
}
}
$pts[] = $pts[0];
$pts[] = $pts[1];
$img->Polygon($pts);
}
// Draw labels for each acc.bar
$x=$pts[2]+($pts[4]-$pts[2])/2;
if($this->bar_shadow) $x += $ssh;
// First stroke the accumulated value for the entire bar
// This value is always placed at the top/bottom of the bars
if( $accy_neg < 0 ) {
$y=$yscale->Translate($accy_neg);
$this->value->Stroke($img,$accy_neg,$x,$y);
}
else {
$y=$yscale->Translate($accy);
$this->value->Stroke($img,$accy,$x,$y);
}
$accy = 0;
$accy_neg = 0;
for($j=0; $j < $this->nbrplots; ++$j ) {
// We don't print 0 values in an accumulated bar plot
if( $this->plots[$j]->coords[0][$i] == 0 ) continue;
if ($this->plots[$j]->coords[0][$i] > 0) {
$yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
$accyt=$yscale->Translate($accy);
if( $this->plots[$j]->valuepos=='center' ) {
$y = $accyt-($accyt-$yt)/2;
}
elseif( $this->plots[$j]->valuepos=='bottom' ) {
$y = $accyt;
}
else { // top or max
$y = $accyt-($accyt-$yt);
}
$accy+=$this->plots[$j]->coords[0][$i];
if( $this->plots[$j]->valuepos=='center' ) {
$this->plots[$j]->value->SetAlign("center","center");
$this->plots[$j]->value->SetMargin(0);
}
elseif( $this->plots[$j]->valuepos=='bottom' ) {
$this->plots[$j]->value->SetAlign('center','bottom');
$this->plots[$j]->value->SetMargin(2);
}
else {
$this->plots[$j]->value->SetAlign('center','top');
$this->plots[$j]->value->SetMargin(1);
}
} else {
$yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
$accyt=$yscale->Translate($accy_neg);
$accy_neg+=$this->plots[$j]->coords[0][$i];
if( $this->plots[$j]->valuepos=='center' ) {
$y = $accyt-($accyt-$yt)/2;
}
elseif( $this->plots[$j]->valuepos=='bottom' ) {
$y = $accyt;
}
else {
$y = $accyt-($accyt-$yt);
}
if( $this->plots[$j]->valuepos=='center' ) {
$this->plots[$j]->value->SetAlign("center","center");
$this->plots[$j]->value->SetMargin(0);
}
elseif( $this->plots[$j]->valuepos=='bottom' ) {
$this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top');
$this->plots[$j]->value->SetMargin(-2);
}
else {
$this->plots[$j]->value->SetAlign('center','bottom');
$this->plots[$j]->value->SetMargin(-1);
}
}
$this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y);
}
}
return true;
}
} // Class
/* EOF */
?>

View File

@ -1,96 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_CANVAS.PHP
// Description: Canvas drawing extension for JpGraph
// Created: 2001-01-08
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_canvas.php 626 2006-05-08 19:06:19Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//===================================================
// CLASS CanvasGraph
// Description: Creates a simple canvas graph which
// might be used together with the basic Image drawing
// primitives. Useful to auickoly produce some arbitrary
// graphic which benefits from all the functionality in the
// graph liek caching for example.
//===================================================
class CanvasGraph extends Graph {
//---------------
// CONSTRUCTOR
function CanvasGraph($aWidth=300,$aHeight=200,$aCachedName="",$timeout=0,$inline=1) {
$this->Graph($aWidth,$aHeight,$aCachedName,$timeout,$inline);
}
//---------------
// PUBLIC METHODS
function InitFrame() {
$this->StrokePlotArea();
}
// Method description
function Stroke($aStrokeFileName="") {
if( $this->texts != null ) {
for($i=0; $i < count($this->texts); ++$i) {
$this->texts[$i]->Stroke($this->img);
}
}
if( $this->iTables !== null ) {
for($i=0; $i < count($this->iTables); ++$i) {
$this->iTables[$i]->Stroke($this->img);
}
}
$this->StrokeTitles();
// If the filename is the predefined value = '_csim_special_'
// we assume that the call to stroke only needs to do enough
// to correctly generate the CSIM maps.
// We use this variable to skip things we don't strictly need
// to do to generate the image map to improve performance
// a best we can. Therefor you will see a lot of tests !$_csim in the
// code below.
$_csim = ($aStrokeFileName===_CSIM_SPECIALFILE);
// We need to know if we have stroked the plot in the
// GetCSIMareas. Otherwise the CSIM hasn't been generated
// and in the case of GetCSIM called before stroke to generate
// CSIM without storing an image to disk GetCSIM must call Stroke.
$this->iHasStroked = true;
if( !$_csim ) {
// Should we do any final image transformation
if( $this->iImgTrans ) {
if( !class_exists('ImgTrans') ) {
require_once('jpgraph_imgtrans.php');
}
$tform = new ImgTrans($this->img->img);
$this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist,
$this->iImgTransDirection,$this->iImgTransHighQ,
$this->iImgTransMinSize,$this->iImgTransFillColor,
$this->iImgTransBorder);
}
// If the filename is given as the special _IMG_HANDLER
// then the image handler is returned and the image is NOT
// streamed back
if( $aStrokeFileName == _IMG_HANDLER ) {
return $this->img->img;
}
else {
// Finally stream the generated picture
$this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName);
return true;
}
}
}
} // Class
/* EOF */
?>

View File

@ -1,516 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_CANVTOOLS.PHP
// Description: Some utilities for text and shape drawing on a canvas
// Created: 2002-08-23
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_canvtools.php 20 2005-05-30 20:34:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
DEFINE('CORNER_TOPLEFT',0);
DEFINE('CORNER_TOPRIGHT',1);
DEFINE('CORNER_BOTTOMRIGHT',2);
DEFINE('CORNER_BOTTOMLEFT',3);
//===================================================
// CLASS CanvasScale
// Description: Define a scale for canvas so we
// can abstract away with absolute pixels
//===================================================
class CanvasScale {
private $g;
private $w,$h;
private $ixmin=0,$ixmax=10,$iymin=0,$iymax=10;
function CanvasScale($graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) {
$this->g = $graph;
$this->w = $graph->img->width;
$this->h = $graph->img->height;
$this->ixmin = $xmin;
$this->ixmax = $xmax;
$this->iymin = $ymin;
$this->iymax = $ymax;
}
function Set($xmin=0,$xmax=10,$ymin=0,$ymax=10) {
$this->ixmin = $xmin;
$this->ixmax = $xmax;
$this->iymin = $ymin;
$this->iymax = $ymax;
}
function Translate($x,$y) {
$xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
$yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
return array($xp,$yp);
}
function TranslateX($x) {
$xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
return $xp;
}
function TranslateY($y) {
$yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
return $yp;
}
}
//===================================================
// CLASS Shape
// Description: Methods to draw shapes on canvas
//===================================================
class Shape {
private $img,$scale;
function Shape($aGraph,$scale) {
$this->img = $aGraph->img;
$this->img->SetColor('black');
$this->scale = $scale;
}
function SetColor($aColor) {
$this->img->SetColor($aColor);
}
function Line($x1,$y1,$x2,$y2) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
$this->img->Line($x1,$y1,$x2,$y2);
}
function Polygon($p,$aClosed=false) {
$n=count($p);
for($i=0; $i < $n; $i+=2 ) {
$p[$i] = $this->scale->TranslateX($p[$i]);
$p[$i+1] = $this->scale->TranslateY($p[$i+1]);
}
$this->img->Polygon($p,$aClosed);
}
function FilledPolygon($p) {
$n=count($p);
for($i=0; $i < $n; $i+=2 ) {
$p[$i] = $this->scale->TranslateX($p[$i]);
$p[$i+1] = $this->scale->TranslateY($p[$i+1]);
}
$this->img->FilledPolygon($p);
}
// Draw a bezier curve with defining points in the $aPnts array
// using $aSteps steps.
// 0=x0, 1=y0
// 2=x1, 3=y1
// 4=x2, 5=y2
// 6=x3, 7=y3
function Bezier($p,$aSteps=40) {
$x0 = $p[0];
$y0 = $p[1];
// Calculate coefficients
$cx = 3*($p[2]-$p[0]);
$bx = 3*($p[4]-$p[2])-$cx;
$ax = $p[6]-$p[0]-$cx-$bx;
$cy = 3*($p[3]-$p[1]);
$by = 3*($p[5]-$p[3])-$cy;
$ay = $p[7]-$p[1]-$cy-$by;
// Step size
$delta = 1.0/$aSteps;
$x_old = $x0;
$y_old = $y0;
for($t=$delta; $t<=1.0; $t+=$delta) {
$tt = $t*$t; $ttt=$tt*$t;
$x = $ax*$ttt + $bx*$tt + $cx*$t + $x0;
$y = $ay*$ttt + $by*$tt + $cy*$t + $y0;
$this->Line($x_old,$y_old,$x,$y);
$x_old = $x;
$y_old = $y;
}
$this->Line($x_old,$y_old,$p[6],$p[7]);
}
function Rectangle($x1,$y1,$x2,$y2) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
$this->img->Rectangle($x1,$y1,$x2,$y2);
}
function FilledRectangle($x1,$y1,$x2,$y2) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
$this->img->FilledRectangle($x1,$y1,$x2,$y2);
}
function Circle($x1,$y1,$r) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
if( $r >= 0 )
$r = $this->scale->TranslateX($r);
else
$r = -$r;
$this->img->Circle($x1,$y1,$r);
}
function FilledCircle($x1,$y1,$r) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
if( $r >= 0 )
$r = $this->scale->TranslateX($r);
else
$r = -$r;
$this->img->FilledCircle($x1,$y1,$r);
}
function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
if( $r == null )
$r = 5;
elseif( $r >= 0 )
$r = $this->scale->TranslateX($r);
else
$r = -$r;
$this->img->RoundedRectangle($x1,$y1,$x2,$y2,$r);
}
function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
if( $r == null )
$r = 5;
elseif( $r > 0 )
$r = $this->scale->TranslateX($r);
else
$r = -$r;
$this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r);
}
function ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102)) {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
list($x2,$y2) = $this->scale->Translate($x2,$y2);
if( $shadow_width == null )
$shadow_width=4;
else
$shadow_width=$this->scale->TranslateX($shadow_width);
$this->img->ShadowRectangle($x1,$y1,$x2,$y2,$fcolor,$shadow_width,$shadow_color);
}
function SetTextAlign($halign,$valign="bottom") {
$this->img->SetTextAlign($halign,$valign="bottom");
}
function StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left") {
list($x1,$y1) = $this->scale->Translate($x1,$y1);
$this->img->StrokeText($x1,$y1,$txt,$dir,$paragraph_align);
}
// A rounded rectangle where one of the corner has been moved "into" the
// rectangle 'iw' width and 'ih' height. Corners:
// 0=Top left, 1=top right, 2=bottom right, 3=bottom left
function IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4) {
list($xt,$yt) = $this->scale->Translate($xt,$yt);
list($w,$h) = $this->scale->Translate($w,$h);
list($iw,$ih) = $this->scale->Translate($iw,$ih);
$xr = $xt + $w - 0;
$yl = $yt + $h - 0;
switch( $aCorner ) {
case 0: // Upper left
// Bottom line, left & right arc
$this->img->Line($xt+$r,$yl,$xr-$r,$yl);
$this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
$this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
// Right line, Top right arc
$this->img->Line($xr,$yt+$r,$xr,$yl-$r);
$this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
// Top line, Top left arc
$this->img->Line($xt+$iw+$r,$yt,$xr-$r,$yt);
$this->img->Arc($xt+$iw+$r,$yt+$r,$r*2,$r*2,180,270);
// Left line
$this->img->Line($xt,$yt+$ih+$r,$xt,$yl-$r);
// Indent horizontal, Lower left arc
$this->img->Line($xt+$r,$yt+$ih,$xt+$iw-$r,$yt+$ih);
$this->img->Arc($xt+$r,$yt+$ih+$r,$r*2,$r*2,180,270);
// Indent vertical, Indent arc
$this->img->Line($xt+$iw,$yt+$r,$xt+$iw,$yt+$ih-$r);
$this->img->Arc($xt+$iw-$r,$yt+$ih-$r,$r*2,$r*2,0,90);
if( $aFillColor != '' ) {
$bc = $this->img->current_color_name;
$this->img->PushColor($aFillColor);
$this->img->FillToBorder($xr-$r,$yl-$r,$bc);
$this->img->PopColor();
}
break;
case 1: // Upper right
// Bottom line, left & right arc
$this->img->Line($xt+$r,$yl,$xr-$r,$yl);
$this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
$this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
// Left line, Top left arc
$this->img->Line($xt,$yt+$r,$xt,$yl-$r);
$this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
// Top line, Top right arc
$this->img->Line($xt+$r,$yt,$xr-$iw-$r,$yt);
$this->img->Arc($xr-$iw-$r,$yt+$r,$r*2,$r*2,270,360);
// Right line
$this->img->Line($xr,$yt+$ih+$r,$xr,$yl-$r);
// Indent horizontal, Lower right arc
$this->img->Line($xr-$iw+$r,$yt+$ih,$xr-$r,$yt+$ih);
$this->img->Arc($xr-$r,$yt+$ih+$r,$r*2,$r*2,270,360);
// Indent vertical, Indent arc
$this->img->Line($xr-$iw,$yt+$r,$xr-$iw,$yt+$ih-$r);
$this->img->Arc($xr-$iw+$r,$yt+$ih-$r,$r*2,$r*2,90,180);
if( $aFillColor != '' ) {
$bc = $this->img->current_color_name;
$this->img->PushColor($aFillColor);
$this->img->FillToBorder($xt+$r,$yl-$r,$bc);
$this->img->PopColor();
}
break;
case 2: // Lower right
// Top line, Top left & Top right arc
$this->img->Line($xt+$r,$yt,$xr-$r,$yt);
$this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
$this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
// Left line, Bottom left arc
$this->img->Line($xt,$yt+$r,$xt,$yl-$r);
$this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
// Bottom line, Bottom right arc
$this->img->Line($xt+$r,$yl,$xr-$iw-$r,$yl);
$this->img->Arc($xr-$iw-$r,$yl-$r,$r*2,$r*2,0,90);
// Right line
$this->img->Line($xr,$yt+$r,$xr,$yl-$ih-$r);
// Indent horizontal, Lower right arc
$this->img->Line($xr-$r,$yl-$ih,$xr-$iw+$r,$yl-$ih);
$this->img->Arc($xr-$r,$yl-$ih-$r,$r*2,$r*2,0,90);
// Indent vertical, Indent arc
$this->img->Line($xr-$iw,$yl-$r,$xr-$iw,$yl-$ih+$r);
$this->img->Arc($xr-$iw+$r,$yl-$ih+$r,$r*2,$r*2,180,270);
if( $aFillColor != '' ) {
$bc = $this->img->current_color_name;
$this->img->PushColor($aFillColor);
$this->img->FillToBorder($xt+$r,$yt+$r,$bc);
$this->img->PopColor();
}
break;
case 3: // Lower left
// Top line, Top left & Top right arc
$this->img->Line($xt+$r,$yt,$xr-$r,$yt);
$this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
$this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
// Right line, Bottom right arc
$this->img->Line($xr,$yt+$r,$xr,$yl-$r);
$this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
// Bottom line, Bottom left arc
$this->img->Line($xt+$iw+$r,$yl,$xr-$r,$yl);
$this->img->Arc($xt+$iw+$r,$yl-$r,$r*2,$r*2,90,180);
// Left line
$this->img->Line($xt,$yt+$r,$xt,$yl-$ih-$r);
// Indent horizontal, Lower left arc
$this->img->Line($xt+$r,$yl-$ih,$xt+$iw-$r,$yl-$ih);
$this->img->Arc($xt+$r,$yl-$ih-$r,$r*2,$r*2,90,180);
// Indent vertical, Indent arc
$this->img->Line($xt+$iw,$yl-$ih+$r,$xt+$iw,$yl-$r);
$this->img->Arc($xt+$iw-$r,$yl-$ih+$r,$r*2,$r*2,270,360);
if( $aFillColor != '' ) {
$bc = $this->img->current_color_name;
$this->img->PushColor($aFillColor);
$this->img->FillToBorder($xr-$r,$yt+$r,$bc);
$this->img->PopColor();
}
break;
}
}
}
//===================================================
// CLASS RectangleText
// Description: Draws a text paragraph inside a
// rounded, possible filled, rectangle.
//===================================================
class CanvasRectangleText {
private $ix,$iy,$iw,$ih,$ir=4;
private $iTxt,$iColor='black',$iFillColor='',$iFontColor='black';
private $iParaAlign='center';
private $iAutoBoxMargin=5;
private $iShadowWidth=3,$iShadowColor='';
function CanvasRectangleText($aTxt='',$xl=0,$yt=0,$w=0,$h=0) {
$this->iTxt = new Text($aTxt);
$this->ix = $xl;
$this->iy = $yt;
$this->iw = $w;
$this->ih = $h;
}
function SetShadow($aColor='gray',$aWidth=3) {
$this->iShadowColor = $aColor;
$this->iShadowWidth = $aWidth;
}
function SetFont($FontFam,$aFontStyle,$aFontSize=12) {
$this->iTxt->SetFont($FontFam,$aFontStyle,$aFontSize);
}
function SetTxt($aTxt) {
$this->iTxt->Set($aTxt);
}
function ParagraphAlign($aParaAlign) {
$this->iParaAlign = $aParaAlign;
}
function SetFillColor($aFillColor) {
$this->iFillColor = $aFillColor;
}
function SetAutoMargin($aMargin) {
$this->iAutoBoxMargin=$aMargin;
}
function SetColor($aColor) {
$this->iColor = $aColor;
}
function SetFontColor($aColor) {
$this->iFontColor = $aColor;
}
function SetPos($xl=0,$yt=0,$w=0,$h=0) {
$this->ix = $xl;
$this->iy = $yt;
$this->iw = $w;
$this->ih = $h;
}
function Pos($xl=0,$yt=0,$w=0,$h=0) {
$this->ix = $xl;
$this->iy = $yt;
$this->iw = $w;
$this->ih = $h;
}
function Set($aTxt,$xl,$yt,$w=0,$h=0) {
$this->iTxt->Set($aTxt);
$this->ix = $xl;
$this->iy = $yt;
$this->iw = $w;
$this->ih = $h;
}
function SetCornerRadius($aRad=5) {
$this->ir = $aRad;
}
function Stroke($aImg,$scale) {
// If coordinates are specifed as negative this means we should
// treat them as abolsute (pixels) coordinates
if( $this->ix > 0 ) {
$this->ix = $scale->TranslateX($this->ix) ;
}
else {
$this->ix = -$this->ix;
}
if( $this->iy > 0 ) {
$this->iy = $scale->TranslateY($this->iy) ;
}
else {
$this->iy = -$this->iy;
}
list($this->iw,$this->ih) = $scale->Translate($this->iw,$this->ih) ;
if( $this->iw == 0 )
$this->iw = round($this->iTxt->GetWidth($aImg) + $this->iAutoBoxMargin);
if( $this->ih == 0 ) {
$this->ih = round($this->iTxt->GetTextHeight($aImg) + $this->iAutoBoxMargin);
}
if( $this->iShadowColor != '' ) {
$aImg->PushColor($this->iShadowColor);
$aImg->FilledRoundedRectangle($this->ix+$this->iShadowWidth,
$this->iy+$this->iShadowWidth,
$this->ix+$this->iw-1+$this->iShadowWidth,
$this->iy+$this->ih-1+$this->iShadowWidth,
$this->ir);
$aImg->PopColor();
}
if( $this->iFillColor != '' ) {
$aImg->PushColor($this->iFillColor);
$aImg->FilledRoundedRectangle($this->ix,$this->iy,
$this->ix+$this->iw-1,
$this->iy+$this->ih-1,
$this->ir);
$aImg->PopColor();
}
if( $this->iColor != '' ) {
$aImg->PushColor($this->iColor);
$aImg->RoundedRectangle($this->ix,$this->iy,
$this->ix+$this->iw-1,
$this->iy+$this->ih-1,
$this->ir);
$aImg->PopColor();
}
$this->iTxt->Align('center','center');
$this->iTxt->ParagraphAlign($this->iParaAlign);
$this->iTxt->SetColor($this->iFontColor);
$this->iTxt->Stroke($aImg, $this->ix+$this->iw/2, $this->iy+$this->ih/2);
return array($this->iw, $this->ih);
}
}
?>

View File

@ -1,495 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_DATE.PHP
// Description: Classes to handle Date scaling
// Created: 2005-05-02
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_date.php 573 2006-03-04 10:41:59Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
DEFINE('HOURADJ_1',0+30);
DEFINE('HOURADJ_2',1+30);
DEFINE('HOURADJ_3',2+30);
DEFINE('HOURADJ_4',3+30);
DEFINE('HOURADJ_6',4+30);
DEFINE('HOURADJ_12',5+30);
DEFINE('MINADJ_1',0+20);
DEFINE('MINADJ_5',1+20);
DEFINE('MINADJ_10',2+20);
DEFINE('MINADJ_15',3+20);
DEFINE('MINADJ_30',4+20);
DEFINE('SECADJ_1',0);
DEFINE('SECADJ_5',1);
DEFINE('SECADJ_10',2);
DEFINE('SECADJ_15',3);
DEFINE('SECADJ_30',4);
DEFINE('YEARADJ_1',0+30);
DEFINE('YEARADJ_2',1+30);
DEFINE('YEARADJ_5',2+30);
DEFINE('MONTHADJ_1',0+20);
DEFINE('MONTHADJ_6',1+20);
DEFINE('DAYADJ_1',0);
DEFINE('DAYADJ_WEEK',1);
DEFINE('DAYADJ_7',1);
DEFINE('SECPERYEAR',31536000);
DEFINE('SECPERDAY',86400);
DEFINE('SECPERHOUR',3600);
DEFINE('SECPERMIN',60);
class DateScale extends LinearScale {
private $date_format = '';
private $iStartAlign = false, $iEndAlign = false;
private $iStartTimeAlign = false, $iEndTimeAlign = false;
//---------------
// CONSTRUCTOR
function DateScale($aMin=0,$aMax=0,$aType='x') {
assert($aType=="x");
assert($aMin<=$aMax);
$this->type=$aType;
$this->scale=array($aMin,$aMax);
$this->world_size=$aMax-$aMin;
$this->ticks = new LinearTicks();
$this->intscale=true;
}
//------------------------------------------------------------------------------------------
// Utility Function AdjDate()
// Description: Will round a given time stamp to an even year, month or day
// argument.
//------------------------------------------------------------------------------------------
function AdjDate($aTime,$aRound=0,$aYearType=false,$aMonthType=false,$aDayType=false) {
$y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime);
$h=0;$i=0;$s=0;
if( $aYearType !== false ) {
$yearAdj = array(0=>1, 1=>2, 2=>5);
if( $aRound == 0 ) {
$y = floor($y/$yearAdj[$aYearType])*$yearAdj[$aYearType];
}
else {
++$y;
$y = ceil($y/$yearAdj[$aYearType])*$yearAdj[$aYearType];
}
$m=1;$d=1;
}
elseif( $aMonthType !== false ) {
$monthAdj = array(0=>1, 1=>6);
if( $aRound == 0 ) {
$m = floor($m/$monthAdj[$aMonthType])*$monthAdj[$aMonthType];
$d=1;
}
else {
++$m;
$m = ceil($m/$monthAdj[$aMonthType])*$monthAdj[$aMonthType];
$d=1;
}
}
elseif( $aDayType !== false ) {
if( $aDayType == 0 ) {
if( $aRound == 1 ) {
//++$d;
$h=23;$i=59;$s=59;
}
}
else {
// Adjust to an even week boundary.
$w = (int)date('w',$aTime); // Day of week 0=Sun, 6=Sat
if( true ) { // Adjust to start on Mon
if( $w==0 ) $w=6;
else --$w;
}
if( $aRound == 0 ) {
$d -= $w;
}
else {
$d += (7-$w);
$h=23;$i=59;$s=59;
}
}
}
return mktime($h,$i,$s,$m,$d,$y);
}
//------------------------------------------------------------------------------------------
// Wrapper for AdjDate that will round a timestamp to an even date rounding
// it downwards.
//------------------------------------------------------------------------------------------
function AdjStartDate($aTime,$aYearType=false,$aMonthType=false,$aDayType=false) {
return $this->AdjDate($aTime,0,$aYearType,$aMonthType,$aDayType);
}
//------------------------------------------------------------------------------------------
// Wrapper for AdjDate that will round a timestamp to an even date rounding
// it upwards
//------------------------------------------------------------------------------------------
function AdjEndDate($aTime,$aYearType=false,$aMonthType=false,$aDayType=false) {
return $this->AdjDate($aTime,1,$aYearType,$aMonthType,$aDayType);
}
//------------------------------------------------------------------------------------------
// Utility Function AdjTime()
// Description: Will round a given time stamp to an even time according to
// argument.
//------------------------------------------------------------------------------------------
function AdjTime($aTime,$aRound=0,$aHourType=false,$aMinType=false,$aSecType=false) {
$y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime);
$h = (int)date('H',$aTime); $i = (int)date('i',$aTime); $s = (int)date('s',$aTime);
if( $aHourType !== false ) {
$aHourType %= 6;
$hourAdj = array(0=>1, 1=>2, 2=>3, 3=>4, 4=>6, 5=>12);
if( $aRound == 0 )
$h = floor($h/$hourAdj[$aHourType])*$hourAdj[$aHourType];
else {
if( ($h % $hourAdj[$aHourType]==0) && ($i > 0 || $s > 0) ) {
$h++;
}
$h = ceil($h/$hourAdj[$aHourType])*$hourAdj[$aHourType];
if( $h >= 24 ) {
$aTime += 86400;
$y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime);
$h -= 24;
}
}
$i=0;$s=0;
}
elseif( $aMinType !== false ) {
$aMinType %= 5;
$minAdj = array(0=>1, 1=>5, 2=>10, 3=>15, 4=>30);
if( $aRound == 0 ) {
$i = floor($i/$minAdj[$aMinType])*$minAdj[$aMinType];
}
else {
if( ($i % $minAdj[$aMinType]==0) && $s > 0 ) {
$i++;
}
$i = ceil($i/$minAdj[$aMinType])*$minAdj[$aMinType];
if( $i >= 60) {
$aTime += 3600;
$y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime);
$h = (int)date('H',$aTime); $i = 0;
}
}
$s=0;
}
elseif( $aSecType !== false ) {
$aSecType %= 5;
$secAdj = array(0=>1, 1=>5, 2=>10, 3=>15, 4=>30);
if( $aRound == 0 ) {
$s = floor($s/$secAdj[$aSecType])*$secAdj[$aSecType];
}
else {
$s = ceil($s/$secAdj[$aSecType]*1.0)*$secAdj[$aSecType];
if( $s >= 60) {
$s=0;
$aTime += 60;
$y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime);
$h = (int)date('H',$aTime); $i = (int)date('i',$aTime);
}
}
}
return mktime($h,$i,$s,$m,$d,$y);
}
//------------------------------------------------------------------------------------------
// Wrapper for AdjTime that will round a timestamp to an even time rounding
// it downwards.
// Example: AdjStartTime(mktime(18,27,13,2,22,2005),false,2) => 18:20
//------------------------------------------------------------------------------------------
function AdjStartTime($aTime,$aHourType=false,$aMinType=false,$aSecType=false) {
return $this->AdjTime($aTime,0,$aHourType,$aMinType,$aSecType);
}
//------------------------------------------------------------------------------------------
// Wrapper for AdjTime that will round a timestamp to an even time rounding
// it upwards
// Example: AdjEndTime(mktime(18,27,13,2,22,2005),false,2) => 18:30
//------------------------------------------------------------------------------------------
function AdjEndTime($aTime,$aHourType=false,$aMinType=false,$aSecType=false) {
return $this->AdjTime($aTime,1,$aHourType,$aMinType,$aSecType);
}
//------------------------------------------------------------------------------------------
// DateAutoScale
// Autoscale a date axis given start and end time
// Returns an array ($start,$end,$major,$minor,$format)
//------------------------------------------------------------------------------------------
function DoDateAutoScale($aStartTime,$aEndTime,$aDensity=0,$aAdjust=true) {
// Format of array
// array ( Decision point, array( array( Major-scale-step-array ),
// array( Minor-scale-step-array ),
// array( 0=date-adjust, 1=time-adjust, adjustment-alignment) )
//
$scalePoints =
array(
/* Intervall larger than 10 years */
SECPERYEAR*10,array(array(SECPERYEAR*5,SECPERYEAR*2),
array(SECPERYEAR),
array(0,YEARADJ_1, 0,YEARADJ_1) ),
/* Intervall larger than 2 years */
SECPERYEAR*2,array(array(SECPERYEAR),array(SECPERYEAR),
array(0,YEARADJ_1) ),
/* Intervall larger than 90 days (approx 3 month) */
SECPERDAY*90,array(array(SECPERDAY*30,SECPERDAY*14,SECPERDAY*7,SECPERDAY),
array(SECPERDAY*5,SECPERDAY*7,SECPERDAY,SECPERDAY),
array(0,MONTHADJ_1, 0,DAYADJ_WEEK, 0,DAYADJ_1, 0,DAYADJ_1)),
/* Intervall larger than 30 days (approx 1 month) */
SECPERDAY*30,array(array(SECPERDAY*14,SECPERDAY*7,SECPERDAY*2, SECPERDAY),
array(SECPERDAY,SECPERDAY.SECPERDAY,SECPERDAY),
array(0,DAYADJ_WEEK, 0,DAYADJ_1, 0,DAYADJ_1, 0,DAYADJ_1)),
/* Intervall larger than 7 days */
SECPERDAY*7,array(array(SECPERDAY,SECPERHOUR*12,SECPERHOUR*6,SECPERHOUR*2),
array(SECPERHOUR*6,SECPERHOUR*3,SECPERHOUR,SECPERHOUR),
array(0,DAYADJ_1, 1,HOURADJ_12, 1,HOURADJ_6, 1,HOURADJ_1)),
/* Intervall larger than 1 day */
SECPERDAY,array(array(SECPERDAY,SECPERHOUR*12,SECPERHOUR*6,SECPERHOUR*2,SECPERHOUR),
array(SECPERHOUR*6,SECPERHOUR*2,SECPERHOUR,SECPERHOUR,SECPERHOUR),
array(1,HOURADJ_12, 1,HOURADJ_6, 1,HOURADJ_1, 1,HOURADJ_1)),
/* Intervall larger than 12 hours */
SECPERHOUR*12,array(array(SECPERHOUR*2,SECPERHOUR,SECPERMIN*30,900,600),
array(1800,1800,900,300,300),
array(1,HOURADJ_1, 1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ),
/* Intervall larger than 2 hours */
SECPERHOUR*2,array(array(SECPERHOUR,SECPERMIN*30,900,600,300),
array(1800,900,300,120,60),
array(1,HOURADJ_1, 1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ),
/* Intervall larger than 1 hours */
SECPERHOUR,array(array(SECPERMIN*30,900,600,300),array(900,300,120,60),
array(1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ),
/* Intervall larger than 30 min */
SECPERMIN*30,array(array(SECPERMIN*15,SECPERMIN*10,SECPERMIN*5,SECPERMIN),
array(300,300,60,10),
array(1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5, 1,MINADJ_1)),
/* Intervall larger than 1 min */
SECPERMIN,array(array(SECPERMIN,15,10,5),
array(15,5,2,1),
array(1,MINADJ_1, 1,SECADJ_15, 1,SECADJ_10, 1,SECADJ_5)),
/* Intervall larger than 10 sec */
10,array(array(5,2),
array(1,1),
array(1,SECADJ_5, 1,SECADJ_1)),
/* Intervall larger than 1 sec */
1,array(array(1),
array(1),
array(1,SECADJ_1)),
);
$ns = count($scalePoints);
// Establish major and minor scale units for the date scale
$diff = $aEndTime - $aStartTime;
if( $diff < 1 ) return false;
$done=false;
$i=0;
while( ! $done ) {
if( $diff > $scalePoints[2*$i] ) {
// Get major and minor scale for this intervall
$scaleSteps = $scalePoints[2*$i+1];
$major = $scaleSteps[0][min($aDensity,count($scaleSteps[0])-1)];
// Try to find out which minor step looks best
$minor = $scaleSteps[1][min($aDensity,count($scaleSteps[1])-1)];
if( $aAdjust ) {
// Find out how we should align the start and end timestamps
$idx = 2*min($aDensity,floor(count($scaleSteps[2])/2)-1);
if( $scaleSteps[2][$idx] === 0 ) {
// Use date adjustment
$adj = $scaleSteps[2][$idx+1];
if( $adj >= 30 ) {
$start = $this->AdjStartDate($aStartTime,$adj-30);
$end = $this->AdjEndDate($aEndTime,$adj-30);
}
elseif( $adj >= 20 ) {
$start = $this->AdjStartDate($aStartTime,false,$adj-20);
$end = $this->AdjEndDate($aEndTime,false,$adj-20);
}
else {
$start = $this->AdjStartDate($aStartTime,false,false,$adj);
$end = $this->AdjEndDate($aEndTime,false,false,$adj);
// We add 1 second for date adjustment to make sure we end on 00:00 the following day
// This makes the final major tick be srawn when we step day-by-day instead of ending
// on xx:59:59 which would not draw the final major tick
$end++;
}
}
else {
// Use time adjustment
$adj = $scaleSteps[2][$idx+1];
if( $adj >= 30 ) {
$start = $this->AdjStartTime($aStartTime,$adj-30);
$end = $this->AdjEndTime($aEndTime,$adj-30);
}
elseif( $adj >= 20 ) {
$start = $this->AdjStartTime($aStartTime,false,$adj-20);
$end = $this->AdjEndTime($aEndTime,false,$adj-20);
}
else {
$start = $this->AdjStartTime($aStartTime,false,false,$adj);
$end = $this->AdjEndTime($aEndTime,false,false,$adj);
}
}
}
// If the overall date span is larger than 1 day ten we show date
$format = '';
if( ($end-$start) > SECPERDAY ) {
$format = 'Y-m-d ';
}
// If the major step is less than 1 day we need to whow hours + min
if( $major < SECPERDAY ) {
$format .= 'H:i';
}
// If the major step is less than 1 min we need to show sec
if( $major < 60 ) {
$format .= ':s';
}
$done=true;
}
++$i;
}
return array($start,$end,$major,$minor,$format);
}
// Overrides the automatic determined date format. Must be a valid date() format string
function SetDateFormat($aFormat) {
$this->date_format = $aFormat;
$this->ticks->SetLabelDateFormat($this->date_format);
}
function SetDateAlign($aStartAlign,$aEndAlign=false) {
if( $aEndAlign === false ) {
$aEndAlign=$aStartAlign;
}
$this->iStartAlign = $aStartAlign;
$this->iEndAlign = $aEndAlign;
}
function SetTimeAlign($aStartAlign,$aEndAlign=false) {
if( $aEndAlign === false ) {
$aEndAlign=$aStartAlign;
}
$this->iStartTimeAlign = $aStartAlign;
$this->iEndTimeAlign = $aEndAlign;
}
function AutoScale($img,$aStartTime,$aEndTime,$aNumSteps,$_adummy=false) {
// We need to have one dummy argument to make the signature of AutoScale()
// identical to LinearScale::AutoScale
if( $aStartTime == $aEndTime ) {
// Special case when we only have one data point.
// Create a small artifical intervall to do the autoscaling
$aStartTime -= 10;
$aEndTime += 10;
}
$done=false;
$i=0;
while( ! $done && $i < 5) {
list($adjstart,$adjend,$maj,$min,$format) = $this->DoDateAutoScale($aStartTime,$aEndTime,$i);
$n = floor(($adjend-$adjstart)/$maj);
if( $n * 1.7 > $aNumSteps ) {
$done=true;
}
$i++;
}
/*
if( 0 ) { // DEBUG
echo " Start =".date("Y-m-d H:i:s",$aStartTime)."<br>";
echo " End =".date("Y-m-d H:i:s",$aEndTime)."<br>";
echo "Adj Start =".date("Y-m-d H:i:s",$adjstart)."<br>";
echo "Adj End =".date("Y-m-d H:i:s",$adjend)."<p>";
echo "Major = $maj s, ".floor($maj/60)."min, ".floor($maj/3600)."h, ".floor($maj/86400)."day<br>";
echo "Min = $min s, ".floor($min/60)."min, ".floor($min/3600)."h, ".floor($min/86400)."day<br>";
echo "Format=$format<p>";
}
*/
if( $this->iStartTimeAlign !== false && $this->iStartAlign !== false ) {
JpGraphError::RaiseL(3001);
//('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both');
}
if( $this->iStartTimeAlign !== false ) {
if( $this->iStartTimeAlign >= 30 ) {
$adjstart = $this->AdjStartTime($aStartTime,$this->iStartTimeAlign-30);
}
elseif( $this->iStartTimeAlign >= 20 ) {
$adjstart = $this->AdjStartTime($aStartTime,false,$this->iStartTimeAlign-20);
}
else {
$adjstart = $this->AdjStartTime($aStartTime,false,false,$this->iStartTimeAlign);
}
}
if( $this->iEndTimeAlign !== false ) {
if( $this->iEndTimeAlign >= 30 ) {
$adjend = $this->AdjEndTime($aEndTime,$this->iEndTimeAlign-30);
}
elseif( $this->iEndTimeAlign >= 20 ) {
$adjend = $this->AdjEndTime($aEndTime,false,$this->iEndTimeAlign-20);
}
else {
$adjend = $this->AdjEndTime($aEndTime,false,false,$this->iEndTimeAlign);
}
}
if( $this->iStartAlign !== false ) {
if( $this->iStartAlign >= 30 ) {
$adjstart = $this->AdjStartDate($aStartTime,$this->iStartAlign-30);
}
elseif( $this->iStartAlign >= 20 ) {
$adjstart = $this->AdjStartDate($aStartTime,false,$this->iStartAlign-20);
}
else {
$adjstart = $this->AdjStartDate($aStartTime,false,false,$this->iStartAlign);
}
}
if( $this->iEndAlign !== false ) {
if( $this->iEndAlign >= 30 ) {
$adjend = $this->AdjEndDate($aEndTime,$this->iEndAlign-30);
}
elseif( $this->iEndAlign >= 20 ) {
$adjend = $this->AdjEndDate($aEndTime,false,$this->iEndAlign-20);
}
else {
$adjend = $this->AdjEndDate($aEndTime,false,false,$this->iEndAlign);
}
}
$this->Update($img,$adjstart,$adjend);
if( ! $this->ticks->IsSpecified() )
$this->ticks->Set($maj,$min);
if( $this->date_format == '' )
$this->ticks->SetLabelDateFormat($format);
else
$this->ticks->SetLabelDateFormat($this->date_format);
}
}
?>

View File

@ -1,157 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_ERROR.PHP
// Description: Error plot extension for JpGraph
// Created: 2001-01-08
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_error.php 462 2006-02-04 12:07:05Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//===================================================
// CLASS ErrorPlot
// Description: Error plot with min/max value for
// each datapoint
//===================================================
class ErrorPlot extends Plot {
private $errwidth=2;
//---------------
// CONSTRUCTOR
function ErrorPlot($datay,$datax=false) {
$this->Plot($datay,$datax);
$this->numpoints /= 2;
}
//---------------
// PUBLIC METHODS
// Gets called before any axis are stroked
function PreStrokeAdjust($graph) {
if( $this->center ) {
$a=0.5; $b=0.5;
++$this->numpoints;
} else {
$a=0; $b=0;
}
$graph->xaxis->scale->ticks->SetXLabelOffset($a);
$graph->SetTextScaleOff($b);
//$graph->xaxis->scale->ticks->SupressMinorTickMarks();
}
// Method description
function Stroke($img,$xscale,$yscale) {
$numpoints=count($this->coords[0])/2;
$img->SetColor($this->color);
$img->SetLineWeight($this->weight);
if( isset($this->coords[1]) ) {
if( count($this->coords[1])!=$numpoints )
JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
//("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
else
$exist_x = true;
}
else
$exist_x = false;
for( $i=0; $i<$numpoints; ++$i) {
if( $exist_x )
$x=$this->coords[1][$i];
else
$x=$i;
if( !is_numeric($x) ||
!is_numeric($this->coords[0][$i*2]) || !is_numeric($this->coords[0][$i*2+1]) ) {
continue;
}
$xt = $xscale->Translate($x);
$yt1 = $yscale->Translate($this->coords[0][$i*2]);
$yt2 = $yscale->Translate($this->coords[0][$i*2+1]);
$img->Line($xt,$yt1,$xt,$yt2);
$img->Line($xt-$this->errwidth,$yt1,$xt+$this->errwidth,$yt1);
$img->Line($xt-$this->errwidth,$yt2,$xt+$this->errwidth,$yt2);
}
return true;
}
} // Class
//===================================================
// CLASS ErrorLinePlot
// Description: Combine a line and error plot
// THIS IS A DEPRECATED PLOT TYPE JUST KEPT FOR
// BACKWARD COMPATIBILITY
//===================================================
class ErrorLinePlot extends ErrorPlot {
public $line=null;
//---------------
// CONSTRUCTOR
function ErrorLinePlot($datay,$datax=false) {
$this->ErrorPlot($datay,$datax);
// Calculate line coordinates as the average of the error limits
$n = count($datay);
for($i=0; $i < $n; $i+=2 ) {
$ly[]=($datay[$i]+$datay[$i+1])/2;
}
$this->line=new LinePlot($ly,$datax);
}
//---------------
// PUBLIC METHODS
function Legend($graph) {
if( $this->legend != "" )
$graph->legend->Add($this->legend,$this->color);
$this->line->Legend($graph);
}
function Stroke($img,$xscale,$yscale) {
parent::Stroke($img,$xscale,$yscale);
$this->line->Stroke($img,$xscale,$yscale);
}
} // Class
//===================================================
// CLASS LineErrorPlot
// Description: Combine a line and error plot
//===================================================
class LineErrorPlot extends ErrorPlot {
public $line=null;
//---------------
// CONSTRUCTOR
// Data is (val, errdeltamin, errdeltamax)
function LineErrorPlot($datay,$datax=false) {
$ly=array(); $ey=array();
$n = count($datay);
if( $n % 3 != 0 ) {
JpGraphError::RaiseL(4002);
//('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3');
}
for($i=0; $i < $n; $i+=3 ) {
$ly[]=$datay[$i];
$ey[]=$datay[$i]+$datay[$i+1];
$ey[]=$datay[$i]+$datay[$i+2];
}
$this->ErrorPlot($ey,$datax);
$this->line=new LinePlot($ly,$datax);
}
//---------------
// PUBLIC METHODS
function Legend($graph) {
if( $this->legend != "" )
$graph->legend->Add($this->legend,$this->color);
$this->line->Legend($graph);
}
function Stroke($img,$xscale,$yscale) {
parent::Stroke($img,$xscale,$yscale);
$this->line->Stroke($img,$xscale,$yscale);
}
} // Class
/* EOF */
?>

View File

@ -1,374 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_FLAGS.PHP
// Description: Class Jpfile. Handles plotmarks
// Created: 2003-06-28
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_flags.php 472 2006-02-04 12:13:48Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
//------------------------------------------------------------
// Defines for the different basic sizes of flags
//------------------------------------------------------------
DEFINE('FLAGSIZE1',1);
DEFINE('FLAGSIZE2',2);
DEFINE('FLAGSIZE3',3);
DEFINE('FLAGSIZE4',4);
class FlagImages {
private $iCountryNameMap = array(
'Afghanistan' => 'afgh',
'Republic of Angola' => 'agla',
'Republic of Albania' => 'alba',
'Alderney' => 'alde',
'Democratic and Popular Republic of Algeria' => 'alge',
'Territory of American Samoa' => 'amsa',
'Principality of Andorra' => 'andr',
'British Overseas Territory of Anguilla' => 'angu',
'Antarctica' => 'anta',
'Argentine Republic' => 'arge',
'League of Arab States' => 'arle',
'Republic of Armenia' => 'arme',
'Aruba' => 'arub',
'Commonwealth of Australia' => 'astl',
'Republic of Austria' => 'aust',
'Azerbaijani Republic' => 'azer',
'British Antarctic Territory' => 'bant',
'Kingdom of Belgium' => 'belg',
'British Overseas Territory of Bermuda' => 'berm',
'Commonwealth of the Bahamas' => 'bhms',
'Kingdom of Bahrain' => 'bhrn',
'Republic of Belarus' => 'blru',
'Republic of Bolivia' => 'blva',
'Belize' => 'blze',
'Republic of Benin' => 'bnin',
'Republic of Botswana' => 'bots',
'Federative Republic of Brazil' => 'braz',
'Barbados' => 'brbd',
'British Indian Ocean Territory' => 'brin',
'Brunei Darussalam' => 'brun',
'Republic of Burkina' => 'bufa',
'Republic of Bulgaria' => 'bulg',
'Republic of Burundi' => 'buru',
'Overseas Territory of the British Virgin Islands' => 'bvis',
'Central African Republic' => 'cafr',
'Kingdom of Cambodia' => 'camb',
'Republic of Cameroon' => 'came',
'Dominion of Canada' => 'cana',
'Caribbean Community' => 'cari',
'Republic of Cape Verde' => 'cave',
'Republic of Chad' => 'chad',
'Republic of Chile' => 'chil',
'Peoples Republic of China' => 'chin',
'Territory of Christmas Island' => 'chms',
'Commonwealth of Independent States' => 'cins',
'Cook Islands' => 'ckis',
'Republic of Colombia' => 'clmb',
'Territory of Cocos Islands' => 'cois',
'Commonwealth' => 'comn',
'Union of the Comoros' => 'como',
'Republic of the Congo' => 'cong',
'Republic of Costa Rica' => 'corc',
'Republic of Croatia' => 'croa',
'Republic of Cuba' => 'cuba',
'British Overseas Territory of the Cayman Islands' => 'cyis',
'Republic of Cyprus' => 'cypr',
'The Czech Republic' => 'czec',
'Kingdom of Denmark' => 'denm',
'Republic of Djibouti' => 'djib',
'Commonwealth of Dominica' => 'domn',
'Dominican Republic' => 'dore',
'Republic of Ecuador' => 'ecua',
'Arab Republic of Egypt' => 'egyp',
'Republic of El Salvador' => 'elsa',
'England' => 'engl',
'Republic of Equatorial Guinea' => 'eqgu',
'State of Eritrea' => 'erit',
'Republic of Estonia' => 'estn',
'Ethiopia' => 'ethp',
'European Union' => 'euun',
'British Overseas Territory of the Falkland Islands' => 'fais',
'International Federation of Vexillological Associations' => 'fiav',
'Republic of Fiji' => 'fiji',
'Republic of Finland' => 'finl',
'Territory of French Polynesia' => 'fpol',
'French Republic' => 'fran',
'Overseas Department of French Guiana' => 'frgu',
'Gabonese Republic' => 'gabn',
'Republic of the Gambia' => 'gamb',
'Republic of Georgia' => 'geor',
'Federal Republic of Germany' => 'germ',
'Republic of Ghana' => 'ghan',
'Gibraltar' => 'gibr',
'Hellenic Republic' => 'grec',
'State of Grenada' => 'gren',
'Overseas Department of Guadeloupe' => 'guad',
'Territory of Guam' => 'guam',
'Republic of Guatemala' => 'guat',
'The Bailiwick of Guernsey' => 'guer',
'Republic of Guinea' => 'guin',
'Republic of Haiti' => 'hait',
'Hong Kong Special Administrative Region' => 'hokn',
'Republic of Honduras' => 'hond',
'Republic of Hungary' => 'hung',
'Republic of Iceland' => 'icel',
'International Committee of the Red Cross' => 'icrc',
'Republic of India' => 'inda',
'Republic of Indonesia' => 'indn',
'Republic of Iraq' => 'iraq',
'Republic of Ireland' => 'irel',
'Organization of the Islamic Conference' => 'isco',
'Isle of Man' => 'isma',
'State of Israel' => 'isra',
'Italian Republic' => 'ital',
'Jamaica' => 'jama',
'Japan' => 'japa',
'The Bailiwick of Jersey' => 'jers',
'Hashemite Kingdom of Jordan' => 'jord',
'Republic of Kazakhstan' => 'kazk',
'Republic of Kenya' => 'keny',
'Republic of Kiribati' => 'kirb',
'State of Kuwait' => 'kuwa',
'Kyrgyz Republic' => 'kyrg',
'Republic of Latvia' => 'latv',
'Lebanese Republic' => 'leba',
'Kingdom of Lesotho' => 'lest',
'Republic of Liberia' => 'libe',
'Principality of Liechtenstein' => 'liec',
'Republic of Lithuania' => 'lith',
'Grand Duchy of Luxembourg' => 'luxe',
'Macao Special Administrative Region' => 'maca',
'Republic of Macedonia' => 'mace',
'Republic of Madagascar' => 'mada',
'Republic of the Marshall Islands' => 'mais',
'Republic of Mali' => 'mali',
'Federation of Malaysia' => 'mals',
'Republic of Malta' => 'malt',
'Republic of Malawi' => 'malw',
'Overseas Department of Martinique' => 'mart',
'Islamic Republic of Mauritania' => 'maur',
'Territorial Collectivity of Mayotte' => 'mayt',
'United Mexican States' => 'mexc',
'Federated States of Micronesia' => 'micr',
'Midway Islands' => 'miis',
'Republic of Moldova' => 'mold',
'Principality of Monaco' => 'mona',
'Republic of Mongolia' => 'mong',
'British Overseas Territory of Montserrat' => 'mont',
'Kingdom of Morocco' => 'morc',
'Republic of Mozambique' => 'moza',
'Republic of Mauritius' => 'mrts',
'Union of Myanmar' => 'myan',
'Republic of Namibia' => 'namb',
'North Atlantic Treaty Organization' => 'nato',
'Republic of Nauru' => 'naur',
'Turkish Republic of Northern Cyprus' => 'ncyp',
'Netherlands Antilles' => 'nean',
'Kingdom of Nepal' => 'nepa',
'Kingdom of the Netherlands' => 'neth',
'Territory of Norfolk Island' => 'nfis',
'Federal Republic of Nigeria' => 'ngra',
'Republic of Nicaragua' => 'nica',
'Republic of Niger' => 'nigr',
'Niue' => 'niue',
'Commonwealth of the Northern Mariana Islands' => 'nmar',
'Province of Northern Ireland' => 'noir',
'Nordic Council' => 'nord',
'Kingdom of Norway' => 'norw',
'Territory of New Caledonia and Dependencies' => 'nwca',
'New Zealand' => 'nwze',
'Organization of American States' => 'oast',
'Organization of African Unity' => 'oaun',
'International Olympic Committee' => 'olym',
'Sultanate of Oman' => 'oman',
'Islamic Republic of Pakistan' => 'paks',
'Republic of Palau' => 'pala',
'Independent State of Papua New Guinea' => 'pang',
'Republic of Paraguay' => 'para',
'Republic of Peru' => 'peru',
'Republic of the Philippines' => 'phil',
'British Overseas Territory of the Pitcairn Islands' => 'piis',
'Republic of Poland' => 'pola',
'Republic of Portugal' => 'port',
'Commonwealth of Puerto Rico' => 'purc',
'State of Qatar' => 'qata',
'Russian Federation' => 'russ',
'Republic of Rwanda' => 'rwan',
'Kingdom of Saudi Arabia' => 'saar',
'Republic of San Marino' => 'sama',
'Nordic Sami Conference' => 'sami',
'Sark' => 'sark',
'Scotland' => 'scot',
'Principality of Seborga' => 'sebo',
'Republic of Sierra Leone' => 'sile',
'Republic of Singapore' => 'sing',
'Republic of Korea' => 'skor',
'Republic of Slovenia' => 'slva',
'Somali Republic' => 'smla',
'Republic of Somaliland' => 'smld',
'Republic of South Africa' => 'soaf',
'Solomon Islands' => 'sois',
'Kingdom of Spain' => 'span',
'Secretariat of the Pacific Community' => 'spco',
'Democratic Socialist Republic of Sri Lanka' => 'srla',
'Saint Lucia' => 'stlu',
'Republic of the Sudan' => 'suda',
'Republic of Suriname' => 'surn',
'Slovak Republic' => 'svka',
'Kingdom of Sweden' => 'swdn',
'Swiss Confederation' => 'swit',
'Syrian Arab Republic' => 'syra',
'Kingdom of Swaziland' => 'szld',
'Republic of China' => 'taiw',
'Taiwan' => 'taiw',
'Republic of Tajikistan' => 'tajk',
'United Republic of Tanzania' => 'tanz',
'Kingdom of Thailand' => 'thal',
'Autonomous Region of Tibet' => 'tibe',
'Turkmenistan' => 'tkst',
'Togolese Republic' => 'togo',
'Tokelau' => 'toke',
'Kingdom of Tonga' => 'tong',
'Tristan da Cunha' => 'trdc',
'Tromelin' => 'tris',
'Republic of Tunisia' => 'tuns',
'Republic of Turkey' => 'turk',
'Tuvalu' => 'tuva',
'United Arab Emirates' => 'uaem',
'Republic of Uganda' => 'ugan',
'Ukraine' => 'ukrn',
'United Kingdom of Great Britain' => 'unkg',
'United Nations' => 'unna',
'United States of America' => 'unst',
'Oriental Republic of Uruguay' => 'urgy',
'Virgin Islands of the United States' => 'usvs',
'Republic of Uzbekistan' => 'uzbk',
'State of the Vatican City' => 'vacy',
'Republic of Vanuatu' => 'vant',
'Bolivarian Republic of Venezuela' => 'venz',
'Republic of Yemen' => 'yemn',
'Democratic Republic of Congo' => 'zare',
'Republic of Zimbabwe' => 'zbwe' ) ;
private $iFlagCount = -1;
private $iFlagSetMap = array(
FLAGSIZE1 => 'flags_thumb35x35',
FLAGSIZE2 => 'flags_thumb60x60',
FLAGSIZE3 => 'flags_thumb100x100',
FLAGSIZE4 => 'flags'
);
private $iFlagData ;
private $iOrdIdx=array();
function FlagImages($aSize=FLAGSIZE1) {
switch($aSize) {
case FLAGSIZE1 :
case FLAGSIZE2 :
case FLAGSIZE3 :
case FLAGSIZE4 :
$file = dirname(__FILE__).'/'.$this->iFlagSetMap[$aSize].'.dat';
$fp = fopen($file,'rb');
$rawdata = fread($fp,filesize($file));
$this->iFlagData = unserialize($rawdata);
break;
default:
JpGraphError::RaiseL(5001,$aSize);
//('Unknown flag size. ('.$aSize.')');
}
$this->iFlagCount = count($this->iCountryNameMap);
}
function GetNum() {
return $this->iFlagCount;
}
function GetImgByName($aName,&$outFullName) {
$idx = $this->GetIdxByName($aName,$outFullName);
return $this->GetImgByIdx($idx);
}
function GetImgByIdx($aIdx) {
if( array_key_exists($aIdx,$this->iFlagData) ) {
$d = $this->iFlagData[$aIdx][1];
return Image::CreateFromString($d);
}
else {
JpGraphError::RaiseL(5002,$aIdx);
//("Flag index \" $aIdx\" does not exist.");
}
}
function GetIdxByOrdinal($aOrd,&$outFullName) {
$aOrd--;
$n = count($this->iOrdIdx);
if( $n == 0 ) {
reset($this->iCountryNameMap);
$this->iOrdIdx=array();
$i=0;
while( list($key,$val) = each($this->iCountryNameMap) ) {
$this->iOrdIdx[$i++] = array($val,$key);
}
$tmp=$this->iOrdIdx[$aOrd];
$outFullName = $tmp[1];
return $tmp[0];
}
elseif( $aOrd >= 0 && $aOrd < $n ) {
$tmp=$this->iOrdIdx[$aOrd];
$outFullName = $tmp[1];
return $tmp[0];
}
else {
JpGraphError::RaiseL(5003,$aOrd);
//('Invalid ordinal number specified for flag index.');
}
}
function GetIdxByName($aName,&$outFullName) {
if( is_integer($aName) ) {
$idx = $this->GetIdxByOrdinal($aName,$outFullName);
return $idx;
}
$found=false;
$aName = strtolower($aName);
$nlen = strlen($aName);
reset($this->iCountryNameMap);
// Start by trying to match exact index name
while( list($key,$val) = each($this->iCountryNameMap) ) {
if( $nlen == strlen($val) && $val == $aName ) {
$found=true;
break;
}
}
if( !$found ) {
reset($this->iCountryNameMap);
// If the exact index doesn't work try a (partial) full name
while( list($key,$val) = each($this->iCountryNameMap) ) {
if( strpos(strtolower($key), $aName) !== false ) {
$found=true;
break;
}
}
}
if( $found ) {
$outFullName = $key;
return $val;
}
else {
JpGraphError::RaiseL(5004,$aName);
//("The (partial) country name \"$aName\" does not have a cooresponding flag image. The flag may still exist but under another name, e.g. insted of \"usa\" try \"united states\".");
}
}
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,424 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_GRADIENT.PHP
// Description: Create a color gradient
// Created: 2003-02-01
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_gradient.php 630 2006-05-26 00:09:30Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
// Styles for gradient color fill
DEFINE("GRAD_VER",1);
DEFINE("GRAD_VERT",1);
DEFINE("GRAD_HOR",2);
DEFINE("GRAD_MIDHOR",3);
DEFINE("GRAD_MIDVER",4);
DEFINE("GRAD_CENTER",5);
DEFINE("GRAD_WIDE_MIDVER",6);
DEFINE("GRAD_WIDE_MIDHOR",7);
DEFINE("GRAD_LEFT_REFLECTION",8);
DEFINE("GRAD_RIGHT_REFLECTION",9);
DEFINE("GRAD_RAISED_PANEL",10);
DEFINE("GRAD_DIAGONAL",11);
//===================================================
// CLASS Gradient
// Description: Handles gradient fills. This is to be
// considered a "friend" class of Class Image.
//===================================================
class Gradient {
private $img=null, $numcolors=100;
//---------------
// CONSTRUCTOR
function Gradient(&$img) {
$this->img = $img;
}
function SetNumColors($aNum) {
$this->numcolors=$aNum;
}
//---------------
// PUBLIC METHODS
// Produce a gradient filled rectangle with a smooth transition between
// two colors.
// ($xl,$yt) Top left corner
// ($xr,$yb) Bottom right
// $from_color Starting color in gradient
// $to_color End color in the gradient
// $style Which way is the gradient oriented?
function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) {
switch( $style ) {
case GRAD_VER:
$steps = round(abs($xr-$xl));
$delta = $xr>=$xl ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
for( $i=0, $x=$xl; $i < $steps; ++$i ) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yt,$x,$yb);
$x += $delta;
}
break;
case GRAD_HOR:
$steps = round(abs($yb-$yt));
$delta = $yb>=$yt ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
for($i=0,$y=$yt; $i < $steps; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
break;
case GRAD_MIDHOR:
$steps = round(abs($yb-$yt)/2);
$delta = $yb >= $yt ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
for($y=$yt, $i=0; $i < $steps; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
--$i;
if( abs($yb-$yt) % 2 == 1 ) --$steps;
for($j=0; $j < $steps; ++$j, --$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
$this->img->Line($xl,$y,$xr,$y);
break;
case GRAD_MIDVER:
$steps = round(abs($xr-$xl)/2);
$delta = $xr>=$xl ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
for($x=$xl, $i=0; $i < $steps; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
--$i;
if( abs($xr-$xl) % 2 == 1 ) --$steps;
for($j=0; $j < $steps; ++$j, --$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
$this->img->Line($x,$yb,$x,$yt);
break;
case GRAD_WIDE_MIDVER:
$diff = round(abs($xr-$xl));
$steps = floor(abs($diff)/3);
$firststep = $diff - 2*$steps ;
$delta = $xr >= $xl ? 1 : -1;
$this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
for($x=$xl, $i=0; $i < $firststep; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
--$i;
$this->img->current_color = $colors[$i];
for($j=0; $j< $steps; ++$j) {
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
for($j=0; $j < $steps; ++$j, --$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
break;
case GRAD_WIDE_MIDHOR:
$diff = round(abs($yb-$yt));
$steps = floor(abs($diff)/3);
$firststep = $diff - 2*$steps ;
$delta = $yb >= $yt? 1 : -1;
$this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
for($y=$yt, $i=0; $i < $firststep; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
--$i;
$this->img->current_color = $colors[$i];
for($j=0; $j < $steps; ++$j) {
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
for($j=0; $j < $steps; ++$j, --$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($xl,$y,$xr,$y);
$y += $delta;
}
break;
case GRAD_LEFT_REFLECTION:
$steps1 = round(0.3*abs($xr-$xl));
$delta = $xr>=$xl ? 1 : -1;
$from_color = $this->img->rgb->Color($from_color);
$adj = 1.4;
$m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
$from_color2 = array(min(255,$from_color[0]+$m),
min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
$this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors);
$n = count($colors);
for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
$steps2 = max(1,round(0.08*abs($xr-$xl)));
$this->img->SetColor($to_color);
for($j=0; $j< $steps2; ++$j) {
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
$steps = abs($xr-$xl)-$steps1-$steps2;
$this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
$n = count($colors);
for($i=0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
break;
case GRAD_RIGHT_REFLECTION:
$steps1 = round(0.7*abs($xr-$xl));
$delta = $xr>=$xl ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors);
$n = count($colors);
for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
$steps2 = max(1,round(0.08*abs($xr-$xl)));
$this->img->SetColor($to_color);
for($j=0; $j< $steps2; ++$j) {
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
$from_color = $this->img->rgb->Color($from_color);
$adj = 1.4;
$m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
$from_color = array(min(255,$from_color[0]+$m),
min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
$steps = abs($xr-$xl)-$steps1-$steps2;
$this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
$n = count($colors);
for($i=0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
break;
case GRAD_CENTER:
$steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2);
$this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
$dx = ($xr-$xl)/2;
$dy = ($yb-$yt)/2;
$x=$xl;$y=$yt;$x2=$xr;$y2=$yb;
$n = count($colors);
for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Rectangle($x,$y,$x2,$y2);
}
$this->img->Line($x,$y,$x2,$y2);
break;
case GRAD_RAISED_PANEL:
// right to left
$steps1 = $xr-$xl;
$delta = $xr>=$xl ? 1 : -1;
$this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors);
$n = count($colors);
for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
// left to right
$xr -= 3;
$xl += 3;
$yb -= 3;
$yt += 3;
$steps2 = $xr-$xl;
$delta = $xr>=$xl ? 1 : -1;
for($x=$xl, $j=$steps2; $j >= 0; --$j) {
$this->img->current_color = $colors[$j];
$this->img->Line($x,$yb,$x,$yt);
$x += $delta;
}
break;
case GRAD_DIAGONAL:
// use the longer dimension to determine the required number of steps.
// first loop draws from one corner to the mid-diagonal and the second
// loop draws from the mid-diagonal to the opposing corner.
if($xr-$xl > $yb - $yt) {
// width is greater than height -> use x-dimension for steps
$steps = $xr-$xl;
$delta = $xr>=$xl ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors);
$n = count($colors);
for($x=$xl, $i=0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$y = $yt+($i/$steps)*($yb-$yt)*$delta;
$this->img->Line($x,$yt,$xl,$y);
$x += $delta;
}
for($x=$xl, $i = 0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$steps+$i];
$y = $yt+($i/$steps)*($yb-$yt)*$delta;
$this->img->Line($x,$yb,$xr,$y);
$x += $delta;
}
} else {
// height is greater than width -> use y-dimension for steps
$steps = $yb-$yt;
$delta = $yb>=$yt ? 1 : -1;
$this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors);
$n = count($colors);
for($y=$yt, $i=0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$i];
$x = $xl+($i/$steps)*($xr-$xl)*$delta;
$this->img->Line($x,$yt,$xl,$y);
$y += $delta;
}
for($y=$yt, $i = 0; $i < $steps && $i < $n; ++$i) {
$this->img->current_color = $colors[$steps+$i];
$x = $xl+($i/$steps)*($xr-$xl)*$delta;
$this->img->Line($x,$yb,$xr,$y);
$x += $delta;
}
}
break;
default:
JpGraphError::RaiseL(7001,$style);
//("Unknown gradient style (=$style).");
break;
}
}
// Fill a special case of a polygon with a flat bottom
// with a gradient. Can be used for filled line plots.
// Please note that this is NOT a generic gradient polygon fill
// routine. It assumes that the bottom is flat (like a drawing
// of a mountain)
function FilledFlatPolygon($pts,$from_color,$to_color) {
if( count($pts) == 0 ) return;
$maxy=$pts[1];
$miny=$pts[1];
$n = count($pts) ;
for( $i=0, $idx=0; $i < $n; $i += 2) {
$x = round($pts[$i]);
$y = round($pts[$i+1]);
$miny = min($miny,$y);
$maxy = max($maxy,$y);
}
$colors = array();
$this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors);
for($i=$miny, $idx=0; $i <= $maxy; ++$i ) {
$colmap[$i] = $colors[$idx++];
}
$n = count($pts)/2 ;
$idx = 0 ;
while( $idx < $n-1 ) {
$p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1]));
$p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1]));
// Find the largest rectangle we can fill
$y = max($p1[1],$p2[1]) ;
for($yy=$maxy; $yy > $y; --$yy) {
$this->img->current_color = $colmap[$yy];
$this->img->Line($p1[0],$yy,$p2[0]-1,$yy);
}
if( $p1[1] == $p2[1] ) continue;
// Fill the rest using lines (slow...)
$slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]);
$x1 = $p1[0];
$x2 = $p2[0]; //-1;
$start = $y;
if( $p1[1] > $p2[1] ) {
while( $y >= $p2[1] ) {
$x1=$slope*($start-$y)+$p1[0];
$this->img->current_color = $colmap[$y];
$this->img->Line($x1,$y,$x2,$y);
--$y;
}
}
else {
while( $y >= $p1[1] ) {
$x2=$p2[0]+$slope*($start-$y);
$this->img->current_color = $colmap[$y];
$this->img->Line($x1,$y,$x2,$y);
--$y;
}
}
}
}
//---------------
// PRIVATE METHODS
// Add to the image color map the necessary colors to do the transition
// between the two colors using $numcolors intermediate colors
function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) {
if( $arr_size==0 ) return;
// If color is given as text get it's corresponding r,g,b values
$from_color = $this->img->rgb->Color($from_color);
$to_color = $this->img->rgb->Color($to_color);
$rdelta=($to_color[0]-$from_color[0])/$numcols;
$gdelta=($to_color[1]-$from_color[1])/$numcols;
$bdelta=($to_color[2]-$from_color[2])/$numcols;
$colorsperstep = $numcols/$arr_size;
$prevcolnum = -1;
$from_alpha = $from_color[3];
$to_alpha = $to_color[3];
$adelta = ( $to_alpha - $from_alpha ) / $numcols ;
for ($i=0; $i < $arr_size; ++$i) {
$colnum = floor($colorsperstep*$i);
if ( $colnum == $prevcolnum )
$colors[$i] = $colidx;
else {
$r = floor($from_color[0] + $colnum*$rdelta);
$g = floor($from_color[1] + $colnum*$gdelta);
$b = floor($from_color[2] + $colnum*$bdelta);
$alpha = $from_alpha + $colnum*$adelta;
$colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha);
$colors[$i] = $colidx;
}
$prevcolnum = $colnum;
}
}
} // Class
?>

View File

@ -1,191 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_ICONPLOT.PHP
// Description: PHP4 Graph Plotting library. Extension module.
// Created: 2004-02-18
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_iconplot.php 575 2006-03-04 11:04:59Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
//===================================================
// CLASS IconPlot
// Description: Make it possible to add a (small) image
// to the graph
//===================================================
class IconPlot {
public $iX=0,$iY=0,$iScale=1.0,$iMix=100;
private $iHorAnchor='left',$iVertAnchor='top';
private $iFile='';
private $iAnchors = array('left','right','top','bottom','center');
private $iCountryFlag='',$iCountryStdSize=3;
private $iScalePosY=null,$iScalePosX=null;
private $iImgString='';
function IconPlot($aFile="",$aX=0,$aY=0,$aScale=1.0,$aMix=100) {
$this->iFile = $aFile;
$this->iX=$aX;
$this->iY=$aY;
$this->iScale= $aScale;
if( $aMix < 0 || $aMix > 100 ) {
JpGraphError::RaiseL(8001); //('Mix value for icon must be between 0 and 100.');
}
$this->iMix = $aMix ;
}
function SetCountryFlag($aFlag,$aX=0,$aY=0,$aScale=1.0,$aMix=100,$aStdSize=3) {
$this->iCountryFlag = $aFlag;
$this->iX=$aX;
$this->iY=$aY;
$this->iScale= $aScale;
if( $aMix < 0 || $aMix > 100 ) {
JpGraphError::RaiseL(8001);//'Mix value for icon must be between 0 and 100.');
}
$this->iMix = $aMix;
$this->iCountryStdSize = $aStdSize;
}
function SetPos($aX,$aY) {
$this->iX=$aX;
$this->iY=$aY;
}
function CreateFromString($aStr) {
$this->iImgString = $aStr;
}
function SetScalePos($aX,$aY) {
$this->iScalePosX = $aX;
$this->iScalePosY = $aY;
}
function SetScale($aScale) {
$this->iScale = $aScale;
}
function SetMix($aMix) {
if( $aMix < 0 || $aMix > 100 ) {
JpGraphError::RaiseL(8001);//('Mix value for icon must be between 0 and 100.');
}
$this->iMix = $aMix ;
}
function SetAnchor($aXAnchor='left',$aYAnchor='center') {
if( !in_array($aXAnchor,$this->iAnchors) ||
!in_array($aYAnchor,$this->iAnchors) ) {
JpGraphError::RaiseL(8002);//("Anchor position for icons must be one of 'top', 'bottom', 'left', 'right' or 'center'");
}
$this->iHorAnchor=$aXAnchor;
$this->iVertAnchor=$aYAnchor;
}
function PreStrokeAdjust($aGraph) {
// Nothing to do ...
}
function DoLegend($aGraph) {
// Nothing to do ...
}
function Max() {
return array(false,false);
}
// The next four function are framework function tht gets called
// from Gantt and is not menaiungfull in the context of Icons but
// they must be implemented to avoid errors.
function GetMaxDate() { return false; }
function GetMinDate() { return false; }
function GetLineNbr() { return 0; }
function GetAbsHeight() {return 0; }
function Min() {
return array(false,false);
}
function StrokeMargin(&$aImg) {
return true;
}
function Stroke($aImg,$axscale,$ayscale) {
$this->StrokeWithScale($aImg,$axscale,$ayscale);
}
function StrokeWithScale($aImg,$axscale,$ayscale) {
if( $this->iScalePosX === null ||
$this->iScalePosY === null ) {
$this->_Stroke($aImg);
}
else {
$this->_Stroke($aImg,
round($axscale->Translate($this->iScalePosX)),
round($ayscale->Translate($this->iScalePosY)));
}
}
function GetWidthHeight() {
$dummy=0;
return $this->_Stroke($dummy,null,null,true);
}
function _Stroke($aImg,$x=null,$y=null,$aReturnWidthHeight=false) {
if( $this->iFile != '' && $this->iCountryFlag != '' ) {
JpGraphError::RaiseL(8003);//('It is not possible to specify both an image file and a country flag for the same icon.');
}
if( $this->iFile != '' ) {
$gdimg = Graph::LoadBkgImage('',$this->iFile);
}
elseif( $this->iImgString != '') {
$gdimg = Image::CreateFromString($this->iImgString);
}
else {
if( ! class_exists('FlagImages',false) ) {
JpGraphError::RaiseL(8004);//('In order to use Country flags as icons you must include the "jpgraph_flags.php" file.');
}
$fobj = new FlagImages($this->iCountryStdSize);
$dummy='';
$gdimg = $fobj->GetImgByName($this->iCountryFlag,$dummy);
}
$iconw = imagesx($gdimg);
$iconh = imagesy($gdimg);
if( $aReturnWidthHeight ) {
return array(round($iconw*$this->iScale),round($iconh*$this->iScale));
}
if( $x !== null && $y !== null ) {
$this->iX = $x; $this->iY = $y;
}
if( $this->iX >= 0 && $this->iX <= 1.0 ) {
$w = imagesx($aImg->img);
$this->iX = round($w*$this->iX);
}
if( $this->iY >= 0 && $this->iY <= 1.0 ) {
$h = imagesy($aImg->img);
$this->iY = round($h*$this->iY);
}
if( $this->iHorAnchor == 'center' )
$this->iX -= round($iconw*$this->iScale/2);
if( $this->iHorAnchor == 'right' )
$this->iX -= round($iconw*$this->iScale);
if( $this->iVertAnchor == 'center' )
$this->iY -= round($iconh*$this->iScale/2);
if( $this->iVertAnchor == 'bottom' )
$this->iY -= round($iconh*$this->iScale);
$aImg->CopyMerge($gdimg,$this->iX,$this->iY,0,0,
round($iconw*$this->iScale),round($iconh*$this->iScale),
$iconw,$iconh,
$this->iMix);
}
}
?>

View File

@ -1,224 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_IMGTRANS.PHP
// Description: Extension for JpGraph to do some simple img transformations
// Created: 2003-09-06
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_imgtrans.php 478 2006-02-04 12:17:06Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
//------------------------------------------------------------------------
// Class ImgTrans
// Perform some simple image transformations.
//------------------------------------------------------------------------
class ImgTrans {
private $gdImg=null;
function ImgTrans($aGdImg) {
// Constructor
$this->gdImg = $aGdImg;
}
// --------------------------------------------------------------------
// _TransVert3D() and _TransHor3D() are helper methods to
// Skew3D().
// --------------------------------------------------------------------
function _TransVert3D($aGdImg,$aHorizon=100,$aSkewDist=120,$aDir=SKEW3D_DOWN,$aMinSize=true,$aFillColor='#FFFFFF',$aQuality=false,$aBorder=false,$aHorizonPos=0.5) {
// Parameter check
if( $aHorizonPos < 0 || $aHorizonPos > 1.0 ) {
JpGraphError::RaiseL(9001);
//("Value for image transformation out of bounds.\nVanishing point on horizon must be specified as a value between 0 and 1.");
}
$w = imagesx($aGdImg);
$h = imagesy($aGdImg);
// Create new image
$ww = $w;
if( $aMinSize )
$hh = ceil($h * $aHorizon / ($aSkewDist+$h));
else
$hh = $h;
$newgdh = imagecreatetruecolor($ww,$hh);
$crgb = new RGB( $newgdh );
$fillColor = $crgb->Allocate($aFillColor);
imagefilledrectangle($newgdh,0,0,$ww-1,$hh-1,$fillColor);
if( $aBorder ) {
$colidx = $crgb->Allocate($aBorder);
imagerectangle($newgdh,0,0,$ww-1,$hh-1,$colidx);
}
$mid = round($w * $aHorizonPos);
$last=$h;
for($y=0; $y < $h; ++$y) {
$yp = $h-$y-1;
$yt = floor($yp * $aHorizon / ($aSkewDist + $yp));
if( !$aQuality ) {
if( $last <= $yt ) continue ;
$last = $yt;
}
for($x=0; $x < $w; ++$x) {
$xt = ($x-$mid) * $aSkewDist / ($aSkewDist + $yp);
if( $aDir == SKEW3D_UP )
$rgb = imagecolorat($aGdImg,$x,$h-$y-1);
else
$rgb = imagecolorat($aGdImg,$x,$y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$colidx = imagecolorallocate($newgdh,$r,$g,$b);
$xt = round($xt+$mid);
if( $aDir == SKEW3D_UP ) {
$syt = $yt;
}
else {
$syt = $hh-$yt-1;
}
if( !empty($set[$yt]) ) {
$nrgb = imagecolorat($newgdh,$xt,$syt);
$nr = ($nrgb >> 16) & 0xFF;
$ng = ($nrgb >> 8) & 0xFF;
$nb = $nrgb & 0xFF;
$colidx = imagecolorallocate($newgdh,floor(($r+$nr)/2),
floor(($g+$ng)/2),floor(($b+$nb)/2));
}
imagesetpixel($newgdh,$xt,$syt,$colidx);
}
$set[$yt] = true;
}
return $newgdh;
}
// --------------------------------------------------------------------
// _TransVert3D() and _TransHor3D() are helper methods to
// Skew3D().
// --------------------------------------------------------------------
function _TransHor3D($aGdImg,$aHorizon=100,$aSkewDist=120,$aDir=SKEW3D_LEFT,$aMinSize=true,$aFillColor='#FFFFFF',$aQuality=false,$aBorder=false,$aHorizonPos=0.5) {
$w = imagesx($aGdImg);
$h = imagesy($aGdImg);
// Create new image
$hh = $h;
if( $aMinSize )
$ww = ceil($w * $aHorizon / ($aSkewDist+$w));
else
$ww = $w;
$newgdh = imagecreatetruecolor($ww,$hh);
$crgb = new RGB( $newgdh );
$fillColor = $crgb->Allocate($aFillColor);
imagefilledrectangle($newgdh,0,0,$ww-1,$hh-1,$fillColor);
if( $aBorder ) {
$colidx = $crgb->Allocate($aBorder);
imagerectangle($newgdh,0,0,$ww-1,$hh-1,$colidx);
}
$mid = round($h * $aHorizonPos);
$last = -1;
for($x=0; $x < $w-1; ++$x) {
$xt = floor($x * $aHorizon / ($aSkewDist + $x));
if( !$aQuality ) {
if( $last >= $xt ) continue ;
$last = $xt;
}
for($y=0; $y < $h; ++$y) {
$yp = $h-$y-1;
$yt = ($yp-$mid) * $aSkewDist / ($aSkewDist + $x);
if( $aDir == SKEW3D_RIGHT )
$rgb = imagecolorat($aGdImg,$w-$x-1,$y);
else
$rgb = imagecolorat($aGdImg,$x,$y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$colidx = imagecolorallocate($newgdh,$r,$g,$b);
$yt = floor($hh-$yt-$mid-1);
if( $aDir == SKEW3D_RIGHT ) {
$sxt = $ww-$xt-1;
}
else
$sxt = $xt ;
if( !empty($set[$xt]) ) {
$nrgb = imagecolorat($newgdh,$sxt,$yt);
$nr = ($nrgb >> 16) & 0xFF;
$ng = ($nrgb >> 8) & 0xFF;
$nb = $nrgb & 0xFF;
$colidx = imagecolorallocate($newgdh,floor(($r+$nr)/2),
floor(($g+$ng)/2),floor(($b+$nb)/2));
}
imagesetpixel($newgdh,$sxt,$yt,$colidx);
}
$set[$xt] = true;
}
return $newgdh;
}
// --------------------------------------------------------------------
// Skew image for the apperance of a 3D effect
// This transforms an image into a 3D-skewed version
// of the image. The transformation is specified by giving the height
// of the artificial horizon and specifying a "skew" factor which
// is the distance on the horizon line between the point of
// convergence and perspective line.
//
// The function returns the GD handle of the transformed image
// leaving the original image untouched.
//
// Parameters:
// * $aGdImg, GD handle to the image to be transformed
// * $aHorizon, Distance to the horizon
// * $aSkewDist, Distance from the horizon point of convergence
// on the horizon line to the perspective points. A larger
// value will fore-shorten the image more
// * $aDir, parameter specifies type of convergence. This of this
// as the walls in a room you are looking at. This specifies if the
// image should be applied on the left,right,top or bottom walls.
// * $aMinSize, true=make the new image just as big as needed,
// false = keep the image the same size as the original image
// * $aFillColor, Background fill color in the image
// * $aHiQuality, true=performa some interpolation that improves
// the image quality but at the expense of performace. Enabling
// high quality will have a dramatic effect on the time it takes
// to transform an image.
// * $aBorder, if set to anything besides false this will draw a
// a border of the speciied color around the image
// --------------------------------------------------------------------
function Skew3D($aHorizon=120,$aSkewDist=150,$aDir=SKEW3D_DOWN,$aHiQuality=false,$aMinSize=true,$aFillColor='#FFFFFF',$aBorder=false) {
return $this->_Skew3D($this->gdImg,$aHorizon,$aSkewDist,$aDir,$aHiQuality,
$aMinSize,$aFillColor,$aBorder);
}
function _Skew3D($aGdImg,$aHorizon=120,$aSkewDist=150,$aDir=SKEW3D_DOWN,$aHiQuality=false,$aMinSize=true,$aFillColor='#FFFFFF',$aBorder=false) {
if( $aDir == SKEW3D_DOWN || $aDir == SKEW3D_UP )
return $this->_TransVert3D($aGdImg,$aHorizon,$aSkewDist,$aDir,$aMinSize,$aFillColor,$aHiQuality,$aBorder);
else
return $this->_TransHor3D($aGdImg,$aHorizon,$aSkewDist,$aDir,$aMinSize,$aFillColor,$aHiQuality,$aBorder);
}
}
?>

View File

@ -1,620 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_LINE.PHP
// Description: Line plot extension for JpGraph
// Created: 2001-01-08
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_line.php 456 2006-02-04 12:02:41Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
require_once ('jpgraph_plotmark.inc.php');
// constants for the (filled) area
DEFINE("LP_AREA_FILLED", true);
DEFINE("LP_AREA_NOT_FILLED", false);
DEFINE("LP_AREA_BORDER",false);
DEFINE("LP_AREA_NO_BORDER",true);
//===================================================
// CLASS LinePlot
// Description:
//===================================================
class LinePlot extends Plot{
public $mark=null;
protected $filled=false;
protected $fill_color='blue';
protected $step_style=false, $center=false;
protected $line_style=1; // Default to solid
protected $filledAreas = array(); // array of arrays(with min,max,col,filled in them)
public $barcenter=false; // When we mix line and bar. Should we center the line in the bar.
protected $fillFromMin = false ;
protected $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100;
protected $iFastStroke=false;
//---------------
// CONSTRUCTOR
function LinePlot($datay,$datax=false) {
$this->Plot($datay,$datax);
$this->mark = new PlotMark() ;
}
//---------------
// PUBLIC METHODS
// Set style, filled or open
function SetFilled($aFlag=true) {
JpGraphError::RaiseL(10001);//('LinePlot::SetFilled() is deprecated. Use SetFillColor()');
}
function SetBarCenter($aFlag=true) {
$this->barcenter=$aFlag;
}
function SetStyle($aStyle) {
$this->line_style=$aStyle;
}
function SetStepStyle($aFlag=true) {
$this->step_style = $aFlag;
}
function SetColor($aColor) {
parent::SetColor($aColor);
}
function SetFillFromYMin($f=true) {
$this->fillFromMin = $f ;
}
function SetFillColor($aColor,$aFilled=true) {
$this->fill_color=$aColor;
$this->filled=$aFilled;
}
function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) {
$this->fillgrad_fromcolor = $aFromColor;
$this->fillgrad_tocolor = $aToColor;
$this->fillgrad_numcolors = $aNumColors;
$this->filled = $aFilled;
$this->fillgrad = true;
}
function Legend($graph) {
if( $this->legend!="" ) {
if( $this->filled && !$this->fillgrad ) {
$graph->legend->Add($this->legend,
$this->fill_color,$this->mark,0,
$this->legendcsimtarget,$this->legendcsimalt);
}
elseif( $this->fillgrad ) {
$color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor);
// In order to differentiate between gradients and cooors specified as an RGB triple
$graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */,
$this->legendcsimtarget,$this->legendcsimalt);
} else {
$graph->legend->Add($this->legend,
$this->color,$this->mark,$this->line_style,
$this->legendcsimtarget,$this->legendcsimalt);
}
}
}
function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) {
if($aMin > $aMax) {
// swap
$tmp = $aMin;
$aMin = $aMax;
$aMax = $tmp;
}
$this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder);
}
// Gets called before any axis are stroked
function PreStrokeAdjust($graph) {
// If another plot type have already adjusted the
// offset we don't touch it.
// (We check for empty in case the scale is a log scale
// and hence doesn't contain any xlabel_offset)
if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
$graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
if( $this->center ) {
++$this->numpoints;
$a=0.5; $b=0.5;
} else {
$a=0; $b=0;
}
$graph->xaxis->scale->ticks->SetXLabelOffset($a);
$graph->SetTextScaleOff($b);
//$graph->xaxis->scale->ticks->SupressMinorTickMarks();
}
}
function SetFastStroke($aFlg=true) {
$this->iFastStroke = $aFlg;
}
function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) {
// An optimized stroke for many data points with no extra
// features but 60% faster. You can't have values or line styles, or null
// values in plots.
$numpoints=count($this->coords[0]);
if( $this->barcenter )
$textadj = 0.5-$xscale->text_scale_off;
else
$textadj = 0;
$img->SetColor($this->color);
$img->SetLineWeight($this->weight);
$pnts=$aStartPoint;
while( $pnts < $numpoints ) {
if( $exist_x ) $x=$this->coords[1][$pnts];
else $x=$pnts+$textadj;
$xt = $xscale->Translate($x);
$y=$this->coords[0][$pnts];
$yt = $yscale->Translate($y);
if( is_numeric($y) ) {
$cord[] = $xt;
$cord[] = $yt;
}
elseif( $y == '-' && $pnts > 0 ) {
// Just ignore
}
else {
JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()');
}
++$pnts;
} // WHILE
$img->Polygon($cord,false,true);
}
function Stroke($img,$xscale,$yscale) {
$idx=0;
$numpoints=count($this->coords[0]);
if( isset($this->coords[1]) ) {
if( count($this->coords[1])!=$numpoints )
JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
//("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
else
$exist_x = true;
}
else
$exist_x = false;
if( $this->barcenter )
$textadj = 0.5-$xscale->text_scale_off;
else
$textadj = 0;
// Find the first numeric data point
$startpoint=0;
while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) )
++$startpoint;
// Bail out if no data points
if( $startpoint == $numpoints )
return;
if( $this->iFastStroke ) {
$this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x);
return;
}
if( $exist_x )
$xs=$this->coords[1][$startpoint];
else
$xs= $textadj+$startpoint;
$img->SetStartPoint($xscale->Translate($xs),
$yscale->Translate($this->coords[0][$startpoint]));
if( $this->filled ) {
$min = $yscale->GetMinVal();
if( $min > 0 || $this->fillFromMin )
$fillmin = $yscale->scale_abs[0];//Translate($min);
else
$fillmin = $yscale->Translate(0);
$cord[$idx++] = $xscale->Translate($xs);
$cord[$idx++] = $fillmin;
}
$xt = $xscale->Translate($xs);
$yt = $yscale->Translate($this->coords[0][$startpoint]);
$cord[$idx++] = $xt;
$cord[$idx++] = $yt;
$yt_old = $yt;
$xt_old = $xt;
$y_old = $this->coords[0][$startpoint];
$this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt);
$img->SetColor($this->color);
$img->SetLineWeight($this->weight);
$img->SetLineStyle($this->line_style);
$pnts=$startpoint+1;
$firstnonumeric = false;
while( $pnts < $numpoints ) {
if( $exist_x ) $x=$this->coords[1][$pnts];
else $x=$pnts+$textadj;
$xt = $xscale->Translate($x);
$yt = $yscale->Translate($this->coords[0][$pnts]);
$y=$this->coords[0][$pnts];
if( $this->step_style ) {
// To handle null values within step style we need to record the
// first non numeric value so we know from where to start if the
// non value is '-'.
if( is_numeric($y) ) {
$firstnonumeric = false;
if( is_numeric($y_old) ) {
$img->StyleLine($xt_old,$yt_old,$xt,$yt_old);
$img->StyleLine($xt,$yt_old,$xt,$yt);
}
elseif( $y_old == '-' ) {
$img->StyleLine($xt_first,$yt_first,$xt,$yt_first);
$img->StyleLine($xt,$yt_first,$xt,$yt);
}
else {
$yt_old = $yt;
$xt_old = $xt;
}
$cord[$idx++] = $xt;
$cord[$idx++] = $yt_old;
$cord[$idx++] = $xt;
$cord[$idx++] = $yt;
}
elseif( $firstnonumeric==false ) {
$firstnonumeric = true;
$yt_first = $yt_old;
$xt_first = $xt_old;
}
}
else {
$tmp1=$y;
$prev=$this->coords[0][$pnts-1];
if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x';
if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x';
if( is_numeric($y) || (is_string($y) && $y != '-') ) {
if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) {
$img->StyleLineTo($xt,$yt);
}
else {
$img->SetStartPoint($xt,$yt);
}
}
if( $this->filled && $tmp1 !== '-' ) {
if( $tmp1 === 'x' ) {
$cord[$idx++] = $cord[$idx-3];
$cord[$idx++] = $fillmin;
}
elseif( $prev === 'x' ) {
$cord[$idx++] = $xt;
$cord[$idx++] = $fillmin;
$cord[$idx++] = $xt;
$cord[$idx++] = $yt;
}
else {
$cord[$idx++] = $xt;
$cord[$idx++] = $yt;
}
}
else {
if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) {
$cord[$idx++] = $xt;
$cord[$idx++] = $yt;
}
}
}
$yt_old = $yt;
$xt_old = $xt;
$y_old = $y;
$this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
++$pnts;
}
if( $this->filled ) {
$cord[$idx++] = $xt;
if( $min > 0 || $this->fillFromMin )
$cord[$idx++] = $yscale->Translate($min);
else
$cord[$idx++] = $yscale->Translate(0);
if( $this->fillgrad ) {
$img->SetLineWeight(1);
$grad = new Gradient($img);
$grad->SetNumColors($this->fillgrad_numcolors);
$grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor);
$img->SetLineWeight($this->weight);
}
else {
$img->SetColor($this->fill_color);
$img->FilledPolygon($cord);
}
if( $this->line_weight > 0 ) {
$img->SetColor($this->color);
$img->Polygon($cord);
}
}
if(!empty($this->filledAreas)) {
$minY = $yscale->Translate($yscale->GetMinVal());
$factor = ($this->step_style ? 4 : 2);
for($i = 0; $i < sizeof($this->filledAreas); ++$i) {
// go through all filled area elements ordered by insertion
// fill polygon array
$areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor];
$areaCoords[] = $minY;
$areaCoords =
array_merge($areaCoords,
array_slice($cord,
$this->filledAreas[$i][0] * $factor,
($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor));
$areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x
$areaCoords[] = $minY; // last y
if($this->filledAreas[$i][3]) {
$img->SetColor($this->filledAreas[$i][2]);
$img->FilledPolygon($areaCoords);
$img->SetColor($this->color);
}
// Check if we should draw the frame.
// If not we still re-draw the line since it might have been
// partially overwritten by the filled area and it doesn't look
// very good.
// TODO: The behaviour is undefined if the line does not have
// any line at the position of the area.
if( $this->filledAreas[$i][4] )
$img->Polygon($areaCoords);
else
$img->Polygon($cord);
$areaCoords = array();
}
}
if( $this->mark->type == -1 || $this->mark->show == false )
return;
for( $pnts=0; $pnts<$numpoints; ++$pnts) {
if( $exist_x ) $x=$this->coords[1][$pnts];
else $x=$pnts+$textadj;
$xt = $xscale->Translate($x);
$yt = $yscale->Translate($this->coords[0][$pnts]);
if( is_numeric($this->coords[0][$pnts]) ) {
if( !empty($this->csimtargets[$pnts]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$pnts]);
$this->mark->SetCSIMAlt($this->csimalts[$pnts]);
}
if( $exist_x )
$x=$this->coords[1][$pnts];
else
$x=$pnts;
$this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x);
$this->mark->Stroke($img,$xt,$yt);
$this->csimareas .= $this->mark->GetCSIMAreas();
$this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
}
}
}
} // Class
//===================================================
// CLASS AccLinePlot
// Description:
//===================================================
class AccLinePlot extends Plot {
protected $plots=null,$nbrplots=0;
private $iStartEndZero=true;
//---------------
// CONSTRUCTOR
function AccLinePlot($plots) {
$this->plots = $plots;
$this->nbrplots = count($plots);
$this->numpoints = $plots[0]->numpoints;
for($i=0; $i < $this->nbrplots; ++$i ) {
$this->LineInterpolate($this->plots[$i]->coords[0]);
}
}
//---------------
// PUBLIC METHODS
function Legend($graph) {
foreach( $this->plots as $p )
$p->DoLegend($graph);
}
function Max() {
list($xmax) = $this->plots[0]->Max();
$nmax=0;
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
$nc = count($this->plots[$i]->coords[0]);
$nmax = max($nmax,$nc);
list($x) = $this->plots[$i]->Max();
$xmax = Max($xmax,$x);
}
for( $i = 0; $i < $nmax; $i++ ) {
// Get y-value for line $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots max y-value since that
// would in most cases give to large y-value.
$y=$this->plots[0]->coords[0][$i];
for( $j = 1; $j < $this->nbrplots; $j++ ) {
$y += $this->plots[ $j ]->coords[0][$i];
}
$ymax[$i] = $y;
}
$ymax = max($ymax);
return array($xmax,$ymax);
}
function Min() {
$nmax=0;
list($xmin,$ysetmin) = $this->plots[0]->Min();
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
$nc = count($this->plots[$i]->coords[0]);
$nmax = max($nmax,$nc);
list($x,$y) = $this->plots[$i]->Min();
$xmin = Min($xmin,$x);
$ysetmin = Min($y,$ysetmin);
}
for( $i = 0; $i < $nmax; $i++ ) {
// Get y-value for line $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots min y-value since that
// would in most cases give to small y-value.
$y=$this->plots[0]->coords[0][$i];
for( $j = 1; $j < $this->nbrplots; $j++ ) {
$y += $this->plots[ $j ]->coords[0][$i];
}
$ymin[$i] = $y;
}
$ymin = Min($ysetmin,Min($ymin));
return array($xmin,$ymin);
}
// Gets called before any axis are stroked
function PreStrokeAdjust($graph) {
// If another plot type have already adjusted the
// offset we don't touch it.
// (We check for empty in case the scale is a log scale
// and hence doesn't contain any xlabel_offset)
if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
$graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
if( $this->center ) {
++$this->numpoints;
$a=0.5; $b=0.5;
} else {
$a=0; $b=0;
}
$graph->xaxis->scale->ticks->SetXLabelOffset($a);
$graph->SetTextScaleOff($b);
$graph->xaxis->scale->ticks->SupressMinorTickMarks();
}
}
function SetInterpolateMode($aIntMode) {
$this->iStartEndZero=$aIntMode;
}
// Replace all '-' with an interpolated value. We use straightforward
// linear interpolation. If the data starts with one or several '-' they
// will be replaced by the the first valid data point
function LineInterpolate(&$aData) {
$n=count($aData);
$i=0;
// If first point is undefined we will set it to the same as the first
// valid data
if( $aData[$i]==='-' ) {
// Find the first valid data
while( $i < $n && $aData[$i]==='-' ) {
++$i;
}
if( $i < $n ) {
for($j=0; $j < $i; ++$j ) {
if( $this->iStartEndZero )
$aData[$i] = 0;
else
$aData[$j] = $aData[$i];
}
}
else {
// All '-' => Error
return false;
}
}
while($i < $n) {
while( $i < $n && $aData[$i] !== '-' ) {
++$i;
}
if( $i < $n ) {
$pstart=$i-1;
// Now see how long this segment of '-' are
while( $i < $n && $aData[$i] === '-' )
++$i;
if( $i < $n ) {
$pend=$i;
$size=$pend-$pstart;
$k=($aData[$pend]-$aData[$pstart])/$size;
// Replace the segment of '-' with a linear interpolated value.
for($j=1; $j < $size; ++$j ) {
$aData[$pstart+$j] = $aData[$pstart] + $j*$k ;
}
}
else {
// There are no valid end point. The '-' goes all the way to the end
// In that case we just set all the remaining values the the same as the
// last valid data point.
for( $j=$pstart+1; $j < $n; ++$j )
if( $this->iStartEndZero )
$aData[$j] = 0;
else
$aData[$j] = $aData[$pstart] ;
}
}
}
return true;
}
// To avoid duplicate of line drawing code here we just
// change the y-values for each plot and then restore it
// after we have made the stroke. We must do this copy since
// it wouldn't be possible to create an acc line plot
// with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl));
// since this method would have a side effect.
function Stroke($img,$xscale,$yscale) {
$img->SetLineWeight($this->weight);
$this->numpoints = count($this->plots[0]->coords[0]);
// Allocate array
$coords[$this->nbrplots][$this->numpoints]=0;
for($i=0; $i<$this->numpoints; $i++) {
$coords[0][$i]=$this->plots[0]->coords[0][$i];
$accy=$coords[0][$i];
for($j=1; $j<$this->nbrplots; ++$j ) {
$coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy;
$accy = $coords[$j][$i];
}
}
for($j=$this->nbrplots-1; $j>=0; --$j) {
$p=$this->plots[$j];
for( $i=0; $i<$this->numpoints; ++$i) {
$tmp[$i]=$p->coords[0][$i];
$p->coords[0][$i]=$coords[$j][$i];
}
$p->Stroke($img,$xscale,$yscale);
for( $i=0; $i<$this->numpoints; ++$i)
$p->coords[0][$i]=$tmp[$i];
$p->coords[0][]=$tmp;
}
}
} // Class
/* EOF */
?>

View File

@ -1,267 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_LOG.PHP
// Description: Log scale plot extension for JpGraph
// Created: 2001-01-08
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_log.php 480 2006-02-04 12:17:57Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
DEFINE('LOGLABELS_PLAIN',0);
DEFINE('LOGLABELS_MAGNITUDE',1);
//===================================================
// CLASS LogScale
// Description: Logarithmic scale between world and screen
//===================================================
class LogScale extends LinearScale {
//---------------
// CONSTRUCTOR
// Log scale is specified using the log of min and max
function LogScale($min,$max,$type="y") {
$this->LinearScale($min,$max,$type);
$this->ticks = new LogTicks();
$this->name = 'log';
}
//----------------
// PUBLIC METHODS
// Translate between world and screen
function Translate($a) {
if( !is_numeric($a) ) {
if( $a != '' && $a != '-' && $a != 'x' )
JpGraphError::RaiseL(11001);
//('Your data contains non-numeric values.');
return 1;
}
if( $a < 0 ) {
JpGraphError::RaiseL(11002);
//("Negative data values can not be used in a log scale.");
exit(1);
}
if( $a==0 ) $a=1;
$a=log10($a);
return ceil($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor);
}
// Relative translate (don't include offset) usefull when we just want
// to know the relative position (in pixels) on the axis
function RelTranslate($a) {
if( !is_numeric($a) ) {
if( $a != '' && $a != '-' && $a != 'x' )
JpGraphError::RaiseL(11001);
//('Your data contains non-numeric values.');
return 1;
}
if( $a==0 ) $a=1;
$a=log10($a);
return round(($a*1.0 - $this->scale[0]) * $this->scale_factor);
}
// Use bcpow() for increased precision
function GetMinVal() {
if( function_exists("bcpow") )
return round(bcpow(10,$this->scale[0],15),14);
else
return round(pow(10,$this->scale[0]),14);
}
function GetMaxVal() {
if( function_exists("bcpow") )
return round(bcpow(10,$this->scale[1],15),14);
else
return round(pow(10,$this->scale[1]),14);
}
// Logarithmic autoscaling is much simplier since we just
// set the min and max to logs of the min and max values.
// Note that for log autoscale the "maxstep" the fourth argument
// isn't used. This is just included to give the method the same
// signature as the linear counterpart.
function AutoScale($img,$min,$max,$maxsteps,$majend=true) {
if( $min==0 ) $min=1;
if( $max <= 0 ) {
JpGraphError::RaiseL(11004);
//('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.');
}
$smin = floor(log10($min));
$smax = ceil(log10($max));
$this->Update($img,$smin,$smax);
}
//---------------
// PRIVATE METHODS
} // Class
//===================================================
// CLASS LogTicks
// Description:
//===================================================
class LogTicks extends Ticks{
private $label_logtype=LOGLABELS_MAGNITUDE;
//---------------
// CONSTRUCTOR
function LogTicks() {
}
//---------------
// PUBLIC METHODS
function IsSpecified() {
return true;
}
function SetLabelLogType($aType) {
$this->label_logtype = $aType;
}
// For log scale it's meaningless to speak about a major step
// We just return -1 to make the framework happy (specifically
// StrokeLabels() )
function GetMajor() {
return -1;
}
function SetTextLabelStart($aStart) {
JpGraphError::RaiseL(11005);
//('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.');
}
function SetXLabelOffset($dummy) {
// For log scales we dont care about XLabel offset
}
// Draw ticks on image "img" using scale "scale". The axis absolute
// position in the image is specified in pos, i.e. for an x-axis
// it specifies the absolute y-coord and for Y-ticks it specified the
// absolute x-position.
function Stroke($img,$scale,$pos) {
$start = $scale->GetMinVal();
$limit = $scale->GetMaxVal();
$nextMajor = 10*$start;
$step = $nextMajor / 10.0;
$img->SetLineWeight($this->weight);
if( $scale->type == "y" ) {
// member direction specified if the ticks should be on
// left or right side.
$a=$pos + $this->direction*$this->GetMinTickAbsSize();
$a2=$pos + $this->direction*$this->GetMajTickAbsSize();
$count=1;
$this->maj_ticks_pos[0]=$scale->Translate($start);
$this->maj_ticklabels_pos[0]=$scale->Translate($start);
if( $this->supress_first )
$this->maj_ticks_label[0]="";
else {
if( $this->label_formfunc != '' ) {
$f = $this->label_formfunc;
$this->maj_ticks_label[0]=call_user_func($f,$start);
}
elseif( $this->label_logtype == LOGLABELS_PLAIN )
$this->maj_ticks_label[0]=$start;
else
$this->maj_ticks_label[0]='10^'.round(log10($start));
}
$i=1;
for($y=$start; $y<=$limit; $y+=$step,++$count ) {
$ys=$scale->Translate($y);
$this->ticks_pos[]=$ys;
$this->ticklabels_pos[]=$ys;
if( $count % 10 == 0 ) {
if( !$this->supress_tickmarks ) {
if( $this->majcolor!="" ) {
$img->PushColor($this->majcolor);
$img->Line($pos,$ys,$a2,$ys);
$img->PopColor();
}
else
$img->Line($pos,$ys,$a2,$ys);
}
$this->maj_ticks_pos[$i]=$ys;
$this->maj_ticklabels_pos[$i]=$ys;
if( $this->label_formfunc != '' ) {
$f = $this->label_formfunc;
$this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
}
elseif( $this->label_logtype == 0 )
$this->maj_ticks_label[$i]=$nextMajor;
else
$this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
++$i;
$nextMajor *= 10;
$step *= 10;
$count=1;
}
else {
if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
if( $this->mincolor!="" ) $img->PushColor($this->mincolor);
$img->Line($pos,$ys,$a,$ys);
if( $this->mincolor!="" ) $img->PopColor();
}
}
}
}
else {
$a=$pos - $this->direction*$this->GetMinTickAbsSize();
$a2=$pos - $this->direction*$this->GetMajTickAbsSize();
$count=1;
$this->maj_ticks_pos[0]=$scale->Translate($start);
$this->maj_ticklabels_pos[0]=$scale->Translate($start);
if( $this->supress_first )
$this->maj_ticks_label[0]="";
else {
if( $this->label_formfunc != '' ) {
$f = $this->label_formfunc;
$this->maj_ticks_label[0]=call_user_func($f,$start);
}
elseif( $this->label_logtype == 0 )
$this->maj_ticks_label[0]=$start;
else
$this->maj_ticks_label[0]='10^'.round(log10($start));
}
$i=1;
for($x=$start; $x<=$limit; $x+=$step,++$count ) {
$xs=$scale->Translate($x);
$this->ticks_pos[]=$xs;
$this->ticklabels_pos[]=$xs;
if( $count % 10 == 0 ) {
if( !$this->supress_tickmarks ) {
$img->Line($xs,$pos,$xs,$a2);
}
$this->maj_ticks_pos[$i]=$xs;
$this->maj_ticklabels_pos[$i]=$xs;
if( $this->label_formfunc != '' ) {
$f = $this->label_formfunc;
$this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
}
elseif( $this->label_logtype == 0 )
$this->maj_ticks_label[$i]=$nextMajor;
else
$this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
++$i;
$nextMajor *= 10;
$step *= 10;
$count=1;
}
else {
if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
$img->Line($xs,$pos,$xs,$a);
}
}
}
}
return true;
}
} // Class
/* EOF */
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,914 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_PIE3D.PHP
// Description: 3D Pie plot extension for JpGraph
// Created: 2001-03-24
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_pie3d.php 571 2006-03-04 10:28:00Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//===================================================
// CLASS PiePlot3D
// Description: Plots a 3D pie with a specified projection
// angle between 20 and 70 degrees.
//===================================================
class PiePlot3D extends PiePlot {
private $labelhintcolor="red",$showlabelhint=true;
private $angle=50;
private $edgecolor="", $edgeweight=1;
private $iThickness=false;
//---------------
// CONSTRUCTOR
function PiePlot3d($data) {
$this->radius = 0.5;
$this->data = $data;
$this->title = new Text("");
$this->title->SetFont(FF_FONT1,FS_BOLD);
$this->value = new DisplayValue();
$this->value->Show();
$this->value->SetFormat('%.0f%%');
}
//---------------
// PUBLIC METHODS
// Set label arrays
function SetLegends($aLegend) {
$this->legends = array_reverse(array_slice($aLegend,0,count($this->data)));
}
function SetSliceColors($aColors) {
$this->setslicecolors = $aColors;
}
function Legend($aGraph) {
parent::Legend($aGraph);
$aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol);
}
function SetCSIMTargets($targets,$alts=null) {
$this->csimtargets = $targets;
$this->csimalts = $alts;
}
// Should the slices be separated by a line? If color is specified as "" no line
// will be used to separate pie slices.
function SetEdge($aColor='black',$aWeight=1) {
$this->edgecolor = $aColor;
$this->edgeweight = $aWeight;
}
// Dummy function to make Pie3D behave in a similair way to 2D
function ShowBorder($exterior=true,$interior=true) {
JpGraphError::RaiseL(14001);
//('Pie3D::ShowBorder() . Deprecated function. Use Pie3D::SetEdge() to control the edges around slices.');
}
// Specify projection angle for 3D in degrees
// Must be between 20 and 70 degrees
function SetAngle($a) {
if( $a<5 || $a>90 )
JpGraphError::RaiseL(14002);
//("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees.");
else
$this->angle = $a;
}
function Add3DSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle
$sa *= M_PI/180;
$ea *= M_PI/180;
//add coordinates of the centre to the map
$coords = "$xc, $yc";
//add coordinates of the first point on the arc to the map
$xp = floor($width*cos($sa)/2+$xc);
$yp = floor($yc-$height*sin($sa)/2);
$coords.= ", $xp, $yp";
//If on the front half, add the thickness offset
if ($sa >= M_PI && $sa <= 2*M_PI*1.01) {
$yp = floor($yp+$thick);
$coords.= ", $xp, $yp";
}
//add coordinates every 0.2 radians
$a=$sa+0.2;
while ($a<$ea) {
$xp = floor($width*cos($a)/2+$xc);
if ($a >= M_PI && $a <= 2*M_PI*1.01) {
$yp = floor($yc-($height*sin($a)/2)+$thick);
} else {
$yp = floor($yc-$height*sin($a)/2);
}
$coords.= ", $xp, $yp";
$a += 0.2;
}
//Add the last point on the arc
$xp = floor($width*cos($ea)/2+$xc);
$yp = floor($yc-$height*sin($ea)/2);
if ($ea >= M_PI && $ea <= 2*M_PI*1.01) {
$coords.= ", $xp, ".floor($yp+$thick);
}
$coords.= ", $xp, $yp";
$alt='';
if( !empty($this->csimalts[$i]) ) {
$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
$alt="alt=\"$tmp\" title=\"$tmp\"";
}
if( !empty($this->csimtargets[$i]) )
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\" $alt />\n";
}
function SetLabels($aLabels,$aLblPosAdj="auto") {
$this->labels = $aLabels;
$this->ilabelposadj=$aLblPosAdj;
}
// Distance from the pie to the labels
function SetLabelMargin($m) {
$this->value->SetMargin($m);
}
// Show a thin line from the pie to the label for a specific slice
function ShowLabelHint($f=true) {
$this->showlabelhint=$f;
}
// Set color of hint line to label for each slice
function SetLabelHintColor($c) {
$this->labelhintcolor=$c;
}
function SetHeight($aHeight) {
$this->iThickness = $aHeight;
}
// Normalize Angle between 0-360
function NormAngle($a) {
// Normalize anle to 0 to 2M_PI
//
if( $a > 0 ) {
while($a > 360) $a -= 360;
}
else {
while($a < 0) $a += 360;
}
if( $a < 0 )
$a = 360 + $a;
if( $a == 360 ) $a=0;
return $a;
}
// Draw one 3D pie slice at position ($xc,$yc) with height $z
function Pie3DSlice($img,$xc,$yc,$w,$h,$sa,$ea,$z,$fillcolor,$shadow=0.65) {
// Due to the way the 3D Pie algorithm works we are
// guaranteed that any slice we get into this method
// belongs to either the left or right side of the
// pie ellipse. Hence, no slice will cross 90 or 270
// point.
if( ($sa < 90 && $ea > 90) || ( ($sa > 90 && $sa < 270) && $ea > 270) ) {
JpGraphError::RaiseL(14003);//('Internal assertion failed. Pie3D::Pie3DSlice');
exit(1);
}
$p[] = array();
// Setup pre-calculated values
$rsa = $sa/180*M_PI; // to Rad
$rea = $ea/180*M_PI; // to Rad
$sinsa = sin($rsa);
$cossa = cos($rsa);
$sinea = sin($rea);
$cosea = cos($rea);
// p[] is the points for the overall slice and
// pt[] is the points for the top pie
// Angular step when approximating the arc with a polygon train.
$step = 0.05;
if( $sa >= 270 ) {
if( $ea > 360 || ($ea > 0 && $ea <= 90) ) {
if( $ea > 0 && $ea <= 90 ) {
// Adjust angle to simplify conditions in loops
$rea += 2*M_PI;
}
$p = array($xc,$yc,$xc,$yc+$z,
$xc+$w*$cossa,$z+$yc-$h*$sinsa);
$pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);
for( $a=$rsa; $a < 2*M_PI; $a += $step ) {
$tca = cos($a);
$tsa = sin($a);
$p[] = $xc+$w*$tca;
$p[] = $z+$yc-$h*$tsa;
$pt[] = $xc+$w*$tca;
$pt[] = $yc-$h*$tsa;
}
$pt[] = $xc+$w;
$pt[] = $yc;
$p[] = $xc+$w;
$p[] = $z+$yc;
$p[] = $xc+$w;
$p[] = $yc;
$p[] = $xc;
$p[] = $yc;
for( $a=2*M_PI+$step; $a < $rea; $a += $step ) {
$pt[] = $xc + $w*cos($a);
$pt[] = $yc - $h*sin($a);
}
$pt[] = $xc+$w*$cosea;
$pt[] = $yc-$h*$sinea;
$pt[] = $xc;
$pt[] = $yc;
}
else {
$p = array($xc,$yc,$xc,$yc+$z,
$xc+$w*$cossa,$z+$yc-$h*$sinsa);
$pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);
$rea = $rea == 0.0 ? 2*M_PI : $rea;
for( $a=$rsa; $a < $rea; $a += $step ) {
$tca = cos($a);
$tsa = sin($a);
$p[] = $xc+$w*$tca;
$p[] = $z+$yc-$h*$tsa;
$pt[] = $xc+$w*$tca;
$pt[] = $yc-$h*$tsa;
}
$pt[] = $xc+$w*$cosea;
$pt[] = $yc-$h*$sinea;
$pt[] = $xc;
$pt[] = $yc;
$p[] = $xc+$w*$cosea;
$p[] = $z+$yc-$h*$sinea;
$p[] = $xc+$w*$cosea;
$p[] = $yc-$h*$sinea;
$p[] = $xc;
$p[] = $yc;
}
}
elseif( $sa >= 180 ) {
$p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea);
$pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);
for( $a=$rea; $a>$rsa; $a -= $step ) {
$tca = cos($a);
$tsa = sin($a);
$p[] = $xc+$w*$tca;
$p[] = $z+$yc-$h*$tsa;
$pt[] = $xc+$w*$tca;
$pt[] = $yc-$h*$tsa;
}
$pt[] = $xc+$w*$cossa;
$pt[] = $yc-$h*$sinsa;
$pt[] = $xc;
$pt[] = $yc;
$p[] = $xc+$w*$cossa;
$p[] = $z+$yc-$h*$sinsa;
$p[] = $xc+$w*$cossa;
$p[] = $yc-$h*$sinsa;
$p[] = $xc;
$p[] = $yc;
}
elseif( $sa >= 90 ) {
if( $ea > 180 ) {
$p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea);
$pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);
for( $a=$rea; $a > M_PI; $a -= $step ) {
$tca = cos($a);
$tsa = sin($a);
$p[] = $xc+$w*$tca;
$p[] = $z + $yc - $h*$tsa;
$pt[] = $xc+$w*$tca;
$pt[] = $yc-$h*$tsa;
}
$p[] = $xc-$w;
$p[] = $z+$yc;
$p[] = $xc-$w;
$p[] = $yc;
$p[] = $xc;
$p[] = $yc;
$pt[] = $xc-$w;
$pt[] = $z+$yc;
$pt[] = $xc-$w;
$pt[] = $yc;
for( $a=M_PI-$step; $a > $rsa; $a -= $step ) {
$pt[] = $xc + $w*cos($a);
$pt[] = $yc - $h*sin($a);
}
$pt[] = $xc+$w*$cossa;
$pt[] = $yc-$h*$sinsa;
$pt[] = $xc;
$pt[] = $yc;
}
else { // $sa >= 90 && $ea <= 180
$p = array($xc,$yc,$xc,$yc+$z,
$xc+$w*$cosea,$z+$yc-$h*$sinea,
$xc+$w*$cosea,$yc-$h*$sinea,
$xc,$yc);
$pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);
for( $a=$rea; $a>$rsa; $a -= $step ) {
$pt[] = $xc + $w*cos($a);
$pt[] = $yc - $h*sin($a);
}
$pt[] = $xc+$w*$cossa;
$pt[] = $yc-$h*$sinsa;
$pt[] = $xc;
$pt[] = $yc;
}
}
else { // sa > 0 && ea < 90
$p = array($xc,$yc,$xc,$yc+$z,
$xc+$w*$cossa,$z+$yc-$h*$sinsa,
$xc+$w*$cossa,$yc-$h*$sinsa,
$xc,$yc);
$pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);
for( $a=$rsa; $a < $rea; $a += $step ) {
$pt[] = $xc + $w*cos($a);
$pt[] = $yc - $h*sin($a);
}
$pt[] = $xc+$w*$cosea;
$pt[] = $yc-$h*$sinea;
$pt[] = $xc;
$pt[] = $yc;
}
$img->PushColor($fillcolor.":".$shadow);
$img->FilledPolygon($p);
$img->PopColor();
$img->PushColor($fillcolor);
$img->FilledPolygon($pt);
$img->PopColor();
}
function SetStartAngle($aStart) {
if( $aStart < 0 || $aStart > 360 ) {
JpGraphError::RaiseL(14004);//('Slice start angle must be between 0 and 360 degrees.');
}
$this->startangle = $aStart;
}
// Draw a 3D Pie
function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z,
$shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) {
//---------------------------------------------------------------------------
// As usual the algorithm get more complicated than I originally
// envisioned. I believe that this is as simple as it is possible
// to do it with the features I want. It's a good exercise to start
// thinking on how to do this to convince your self that all this
// is really needed for the general case.
//
// The algorithm two draw 3D pies without "real 3D" is done in
// two steps.
// First imagine the pie cut in half through a thought line between
// 12'a clock and 6'a clock. It now easy to imagine that we can plot
// the individual slices for each half by starting with the topmost
// pie slice and continue down to 6'a clock.
//
// In the algortithm this is done in three principal steps
// Step 1. Do the knife cut to ensure by splitting slices that extends
// over the cut line. This is done by splitting the original slices into
// upto 3 subslices.
// Step 2. Find the top slice for each half
// Step 3. Draw the slices from top to bottom
//
// The thing that slightly complicates this scheme with all the
// angle comparisons below is that we can have an arbitrary start
// angle so we must take into account the different equivalence classes.
// For the same reason we must walk through the angle array in a
// modulo fashion.
//
// Limitations of algorithm:
// * A small exploded slice which crosses the 270 degree point
// will get slightly nagged close to the center due to the fact that
// we print the slices in Z-order and that the slice left part
// get printed first and might get slightly nagged by a larger
// slice on the right side just before the right part of the small
// slice. Not a major problem though.
//---------------------------------------------------------------------------
// Determine the height of the ellippse which gives an
// indication of the inclination angle
$h = ($angle/90.0)*$d;
$sum = 0;
for($i=0; $i<count($data); ++$i ) {
$sum += $data[$i];
}
// Special optimization
if( $sum==0 ) return;
if( $this->labeltype == 2 ) {
$this->adjusted_data = $this->AdjPercentage($data);
}
// Setup the start
$accsum = 0;
$a = $startangle;
$a = $this->NormAngle($a);
//
// Step 1 . Split all slices that crosses 90 or 270
//
$idx=0;
$adjexplode=array();
$numcolors = count($colors);
for($i=0; $i<count($data); ++$i, ++$idx ) {
$da = $data[$i]/$sum * 360;
if( empty($this->explode_radius[$i]) )
$this->explode_radius[$i]=0;
$expscale=1;
if( $aaoption == 1 )
$expscale=2;
$la = $a + $da/2;
$explode = array( $xc + $this->explode_radius[$i]*cos($la*M_PI/180)*$expscale,
$yc - $this->explode_radius[$i]*sin($la*M_PI/180) * ($h/$d) *$expscale );
$adjexplode[$idx] = $explode;
$labeldata[$i] = array($la,$explode[0],$explode[1]);
$originalangles[$i] = array($a,$a+$da);
$ne = $this->NormAngle($a+$da);
if( $da <= 180 ) {
// If the slice size is <= 90 it can at maximum cut across
// one boundary (either 90 or 270) where it needs to be split
$split=-1; // no split
if( ($da<=90 && ($a <= 90 && $ne > 90)) ||
(($da <= 180 && $da >90) && (($a < 90 || $a >= 270) && $ne > 90)) ) {
$split = 90;
}
elseif( ($da<=90 && ($a <= 270 && $ne > 270)) ||
(($da<=180 && $da>90) && ($a >= 90 && $a < 270 && ($a+$da) > 270 )) ) {
$split = 270;
}
if( $split > 0 ) { // split in two
$angles[$idx] = array($a,$split);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
$angles[++$idx] = array($split,$ne);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
}
else { // no split
$angles[$idx] = array($a,$ne);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
}
}
else {
// da>180
// Slice may, depending on position, cross one or two
// bonudaries
if( $a < 90 )
$split = 90;
elseif( $a <= 270 )
$split = 270;
else
$split = 90;
$angles[$idx] = array($a,$split);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
//if( $a+$da > 360-$split ) {
// For slices larger than 270 degrees we might cross
// another boundary as well. This means that we must
// split the slice further. The comparison gets a little
// bit complicated since we must take into accound that
// a pie might have a startangle >0 and hence a slice might
// wrap around the 0 angle.
// Three cases:
// a) Slice starts before 90 and hence gets a split=90, but
// we must also check if we need to split at 270
// b) Slice starts after 90 but before 270 and slices
// crosses 90 (after a wrap around of 0)
// c) If start is > 270 (hence the firstr split is at 90)
// and the slice is so large that it goes all the way
// around 270.
if( ($a < 90 && ($a+$da > 270)) ||
($a > 90 && $a<=270 && ($a+$da>360+90) ) ||
($a > 270 && $this->NormAngle($a+$da)>270) ) {
$angles[++$idx] = array($split,360-$split);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
$angles[++$idx] = array(360-$split,$ne);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
}
else {
// Just a simple split to the previous decided
// angle.
$angles[++$idx] = array($split,$ne);
$adjcolors[$idx] = $colors[$i % $numcolors];
$adjexplode[$idx] = $explode;
}
}
$a += $da;
$a = $this->NormAngle($a);
}
// Total number of slices
$n = count($angles);
for($i=0; $i<$n; ++$i) {
list($dbgs,$dbge) = $angles[$i];
}
//
// Step 2. Find start index (first pie that starts in upper left quadrant)
//
$minval = $angles[0][0];
$min = 0;
for( $i=0; $i<$n; ++$i ) {
if( $angles[$i][0] < $minval ) {
$minval = $angles[$i][0];
$min = $i;
}
}
$j = $min;
$cnt = 0;
while( $angles[$j][1] <= 90 ) {
$j++;
if( $j>=$n) {
$j=0;
}
if( $cnt > $n ) {
JpGraphError::RaiseL(14005);
//("Pie3D Internal error (#1). Trying to wrap twice when looking for start index");
}
++$cnt;
}
$start = $j;
//
// Step 3. Print slices in z-order
//
$cnt = 0;
// First stroke all the slices between 90 and 270 (left half circle)
// counterclockwise
while( $angles[$j][0] < 270 && $aaoption !== 2 ) {
list($x,$y) = $adjexplode[$j];
$this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1],
$z,$adjcolors[$j],$shadow);
$last = array($x,$y,$j);
$j++;
if( $j >= $n ) $j=0;
if( $cnt > $n ) {
JpGraphError::RaiseL(14006);
//("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking.");
}
++$cnt;
}
$slice_left = $n-$cnt;
$j=$start-1;
if($j<0) $j=$n-1;
$cnt = 0;
// The stroke all slices from 90 to -90 (right half circle)
// clockwise
while( $cnt < $slice_left && $aaoption !== 2 ) {
list($x,$y) = $adjexplode[$j];
$this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1],
$z,$adjcolors[$j],$shadow);
$j--;
if( $cnt > $n ) {
JpGraphError::RaiseL(14006);
//("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking.");
}
if($j<0) $j=$n-1;
$cnt++;
}
// Now do a special thing. Stroke the last slice on the left
// halfcircle one more time. This is needed in the case where
// the slice close to 270 have been exploded. In that case the
// part of the slice close to the center of the pie might be
// slightly nagged.
if( $aaoption !== 2 )
$this->Pie3DSlice($img,$last[0],$last[1],$d,$h,$angles[$last[2]][0],
$angles[$last[2]][1],$z,$adjcolors[$last[2]],$shadow);
if( $aaoption !== 1 ) {
// Now print possible labels and add csim
$this->value->ApplyFont($img);
$margin = $img->GetFontHeight()/2 + $this->value->margin ;
for($i=0; $i < count($data); ++$i ) {
$la = $labeldata[$i][0];
$x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin)*$this->ilabelposadj;
$y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin)*$this->ilabelposadj;
if( $this->ilabelposadj >= 1.0 ) {
if( $la > 180 && $la < 360 ) $y += $z;
}
if( $this->labeltype == 0 ) {
if( $sum > 0 )
$l = 100*$data[$i]/$sum;
else
$l = 0;
}
elseif( $this->labeltype == 1 ) {
$l = $data[$i];
}
else {
$l = $this->adjusted_data[$i];
}
if( isset($this->labels[$i]) && is_string($this->labels[$i]) )
$l=sprintf($this->labels[$i],$l);
$this->StrokeLabels($l,$img,$labeldata[$i][0]*M_PI/180,$x,$y,$z);
$this->Add3DSliceToCSIM($i,$labeldata[$i][1],$labeldata[$i][2],$h*2,$d*2,$z,
$originalangles[$i][0],$originalangles[$i][1]);
}
}
//
// Finally add potential lines in pie
//
if( $edgecolor=="" || $aaoption !== 0 ) return;
$accsum = 0;
$a = $startangle;
$a = $this->NormAngle($a);
$a *= M_PI/180.0;
$idx=0;
$img->PushColor($edgecolor);
$img->SetLineWeight($edgeweight);
$fulledge = true;
for($i=0; $i < count($data) && $fulledge; ++$i ) {
if( empty($this->explode_radius[$i]) )
$this->explode_radius[$i]=0;
if( $this->explode_radius[$i] > 0 ) {
$fulledge = false;
}
}
for($i=0; $i < count($data); ++$i, ++$idx ) {
$da = $data[$i]/$sum * 2*M_PI;
$this->StrokeFullSliceFrame($img,$xc,$yc,$a,$a+$da,$d,$h,$z,$edgecolor,
$this->explode_radius[$i],$fulledge);
$a += $da;
}
$img->PopColor();
}
function StrokeFullSliceFrame($img,$xc,$yc,$sa,$ea,$w,$h,$z,$edgecolor,$exploderadius,$fulledge) {
$step = 0.02;
if( $exploderadius > 0 ) {
$la = ($sa+$ea)/2;
$xc += $exploderadius*cos($la);
$yc -= $exploderadius*sin($la) * ($h/$w) ;
}
$p = array($xc,$yc,$xc+$w*cos($sa),$yc-$h*sin($sa));
for($a=$sa; $a < $ea; $a += $step ) {
$p[] = $xc + $w*cos($a);
$p[] = $yc - $h*sin($a);
}
$p[] = $xc+$w*cos($ea);
$p[] = $yc-$h*sin($ea);
$p[] = $xc;
$p[] = $yc;
$img->SetColor($edgecolor);
$img->Polygon($p);
// Unfortunately we can't really draw the full edge around the whole of
// of the slice if any of the slices are exploded. The reason is that
// this algorithm is to simply. There are cases where the edges will
// "overwrite" other slices when they have been exploded.
// Doing the full, proper 3D hidden lines stiff is actually quite
// tricky. So for exploded pies we only draw the top edge. Not perfect
// but the "real" solution is much more complicated.
if( $fulledge && !( $sa > 0 && $sa < M_PI && $ea < M_PI) ) {
if($sa < M_PI && $ea > M_PI)
$sa = M_PI;
if($sa < 2*M_PI && (($ea >= 2*M_PI) || ($ea > 0 && $ea < $sa ) ) )
$ea = 2*M_PI;
if( $sa >= M_PI && $ea <= 2*M_PI ) {
$p = array($xc + $w*cos($sa),$yc - $h*sin($sa),
$xc + $w*cos($sa),$z + $yc - $h*sin($sa));
for($a=$sa+$step; $a < $ea; $a += $step ) {
$p[] = $xc + $w*cos($a);
$p[] = $z + $yc - $h*sin($a);
}
$p[] = $xc + $w*cos($ea);
$p[] = $z + $yc - $h*sin($ea);
$p[] = $xc + $w*cos($ea);
$p[] = $yc - $h*sin($ea);
$img->SetColor($edgecolor);
$img->Polygon($p);
}
}
}
function Stroke($img,$aaoption=0) {
$n = count($this->data);
// If user hasn't set the colors use the theme array
if( $this->setslicecolors==null ) {
$colors = array_keys($img->rgb->rgb_table);
sort($colors);
$idx_a=$this->themearr[$this->theme];
$ca = array();
$m = count($idx_a);
for($i=0; $i < $m; ++$i)
$ca[$i] = $colors[$idx_a[$i]];
$ca = array_reverse(array_slice($ca,0,$n));
}
else {
$ca = $this->setslicecolors;
}
if( $this->posx <= 1 && $this->posx > 0 )
$xc = round($this->posx*$img->width);
else
$xc = $this->posx ;
if( $this->posy <= 1 && $this->posy > 0 )
$yc = round($this->posy*$img->height);
else
$yc = $this->posy ;
if( $this->radius <= 1 ) {
$width = floor($this->radius*min($img->width,$img->height));
// Make sure that the pie doesn't overflow the image border
// The 0.9 factor is simply an extra margin to leave some space
// between the pie an the border of the image.
$width = min($width,min($xc*0.9,($yc*90/$this->angle-$width/4)*0.9));
}
else {
$width = $this->radius * ($aaoption === 1 ? 2 : 1 ) ;
}
// Add a sanity check for width
if( $width < 1 ) {
JpGraphError::RaiseL(14007);//("Width for 3D Pie is 0. Specify a size > 0");
}
// Establish a thickness. By default the thickness is a fifth of the
// pie slice width (=pie radius) but since the perspective depends
// on the inclination angle we use some heuristics to make the edge
// slightly thicker the less the angle.
// Has user specified an absolute thickness? In that case use
// that instead
if( $this->iThickness ) {
$thick = $this->iThickness;
$thick *= ($aaoption === 1 ? 2 : 1 );
}
else
$thick = $width/12;
$a = $this->angle;
if( $a <= 30 ) $thick *= 1.6;
elseif( $a <= 40 ) $thick *= 1.4;
elseif( $a <= 50 ) $thick *= 1.2;
elseif( $a <= 60 ) $thick *= 1.0;
elseif( $a <= 70 ) $thick *= 0.8;
elseif( $a <= 80 ) $thick *= 0.7;
else $thick *= 0.6;
$thick = floor($thick);
if( $this->explode_all )
for($i=0; $i < $n; ++$i)
$this->explode_radius[$i]=$this->explode_r;
$this->Pie3D($aaoption,$img,$this->data, $ca, $xc, $yc, $width, $this->angle,
$thick, 0.65, $this->startangle, $this->edgecolor, $this->edgeweight);
// Adjust title position
if( $aaoption != 1 ) {
$this->title->SetPos($xc,$yc-$this->title->GetFontHeight($img)-$width/2-$this->title->margin, "center","bottom");
$this->title->Stroke($img);
}
}
//---------------
// PRIVATE METHODS
// Position the labels of each slice
function StrokeLabels($label,$img,$a,$xp,$yp,$z) {
$this->value->halign="left";
$this->value->valign="top";
// Position the axis title.
// dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
// that intersects with the extension of the corresponding axis. The code looks a little
// bit messy but this is really the only way of having a reasonable position of the
// axis titles.
$this->value->ApplyFont($img);
$h=$img->GetTextHeight($label);
// For numeric values the format of the display value
// must be taken into account
if( is_numeric($label) ) {
if( $label >= 0 )
$w=$img->GetTextWidth(sprintf($this->value->format,$label));
else
$w=$img->GetTextWidth(sprintf($this->value->negformat,$label));
}
else
$w=$img->GetTextWidth($label);
while( $a > 2*M_PI ) $a -= 2*M_PI;
if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI);
if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
$x = round($xp-$dx*$w);
$y = round($yp-$dy*$h);
// Mark anchor point for debugging
/*
$img->SetColor('red');
$img->Line($xp-10,$yp,$xp+10,$yp);
$img->Line($xp,$yp-10,$xp,$yp+10);
*/
$oldmargin = $this->value->margin;
$this->value->margin=0;
$this->value->Stroke($img,$label,$x,$y);
$this->value->margin=$oldmargin;
}
} // Class
/* EOF */
?>

View File

@ -1,636 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_PLOTBAND.PHP
// Description: PHP4 Graph Plotting library. Extension module.
// Created: 2004-02-18
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_plotband.php 484 2006-02-04 12:20:01Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
// Constants for types of static bands in plot area
DEFINE("BAND_RDIAG",1); // Right diagonal lines
DEFINE("BAND_LDIAG",2); // Left diagonal lines
DEFINE("BAND_SOLID",3); // Solid one color
DEFINE("BAND_VLINE",4); // Vertical lines
DEFINE("BAND_HLINE",5); // Horizontal lines
DEFINE("BAND_3DPLANE",6); // "3D" Plane
DEFINE("BAND_HVCROSS",7); // Vertical/Hor crosses
DEFINE("BAND_DIAGCROSS",8); // Diagonal crosses
// Utility class to hold coordinates for a rectangle
class Rectangle {
public $x,$y,$w,$h;
public $xe, $ye;
function Rectangle($aX,$aY,$aWidth,$aHeight) {
$this->x=$aX;
$this->y=$aY;
$this->w=$aWidth;
$this->h=$aHeight;
$this->xe=$aX+$aWidth-1;
$this->ye=$aY+$aHeight-1;
}
}
//=====================================================================
// Class RectPattern
// Base class for pattern hierarchi that is used to display patterned
// bands on the graph. Any subclass that doesn't override Stroke()
// must at least implement method DoPattern($aImg) which is responsible
// for drawing the pattern onto the graph.
//=====================================================================
class RectPattern {
protected $color;
protected $weight;
protected $rect=null;
protected $doframe=true;
protected $linespacing; // Line spacing in pixels
protected $iBackgroundColor=-1; // Default is no background fill
function RectPattern($aColor,$aWeight=1) {
$this->color = $aColor;
$this->weight = $aWeight;
}
function SetBackground($aBackgroundColor) {
$this->iBackgroundColor=$aBackgroundColor;
}
function SetPos($aRect) {
$this->rect = $aRect;
}
function ShowFrame($aShow=true) {
$this->doframe=$aShow;
}
function SetDensity($aDens) {
if( $aDens < 1 || $aDens > 100 )
JpGraphError::RaiseL(16001,$aDens);
//(" Desity for pattern must be between 1 and 100. (You tried $aDens)");
// 1% corresponds to linespacing=50
// 100 % corresponds to linespacing 1
$this->linespacing = floor(((100-$aDens)/100.0)*50)+1;
}
function Stroke($aImg) {
if( $this->rect == null )
JpGraphError::RaiseL(16002);
//(" No positions specified for pattern.");
if( !(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor==-1) ) {
$aImg->SetColor($this->iBackgroundColor);
$aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
}
$aImg->SetColor($this->color);
$aImg->SetLineWeight($this->weight);
// Virtual function implemented by subclass
$this->DoPattern($aImg);
// Frame around the pattern area
if( $this->doframe )
$aImg->Rectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
}
}
//=====================================================================
// Class RectPatternSolid
// Implements a solid band
//=====================================================================
class RectPatternSolid extends RectPattern {
function RectPatternSolid($aColor="black",$aWeight=1) {
parent::RectPattern($aColor,$aWeight);
}
function DoPattern($aImg) {
$aImg->SetColor($this->color);
$aImg->FilledRectangle($this->rect->x,$this->rect->y,
$this->rect->xe,$this->rect->ye);
}
}
//=====================================================================
// Class RectPatternHor
// Implements horizontal line pattern
//=====================================================================
class RectPatternHor extends RectPattern {
function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) {
parent::RectPattern($aColor,$aWeight);
$this->linespacing = $aLineSpacing;
}
function DoPattern($aImg) {
$x0 = $this->rect->x;
$x1 = $this->rect->xe;
$y = $this->rect->y;
while( $y < $this->rect->ye ) {
$aImg->Line($x0,$y,$x1,$y);
$y += $this->linespacing;
}
}
}
//=====================================================================
// Class RectPatternVert
// Implements vertical line pattern
//=====================================================================
class RectPatternVert extends RectPattern {
function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) {
parent::RectPattern($aColor,$aWeight);
$this->linespacing = $aLineSpacing;
}
//--------------------
// Private methods
//
function DoPattern($aImg) {
$x = $this->rect->x;
$y0 = $this->rect->y;
$y1 = $this->rect->ye;
while( $x < $this->rect->xe ) {
$aImg->Line($x,$y0,$x,$y1);
$x += $this->linespacing;
}
}
}
//=====================================================================
// Class RectPatternRDiag
// Implements right diagonal pattern
//=====================================================================
class RectPatternRDiag extends RectPattern {
function RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
parent::RectPattern($aColor,$aWeight);
$this->linespacing = $aLineSpacing;
}
function DoPattern($aImg) {
// --------------------
// | / / / / /|
// |/ / / / / |
// | / / / / |
// --------------------
$xe = $this->rect->xe;
$ye = $this->rect->ye;
$x0 = $this->rect->x + round($this->linespacing/2);
$y0 = $this->rect->y;
$x1 = $this->rect->x;
$y1 = $this->rect->y + round($this->linespacing/2);
while($x0<=$xe && $y1<=$ye) {
$aImg->Line($x0,$y0,$x1,$y1);
$x0 += $this->linespacing;
$y1 += $this->linespacing;
}
if( $xe-$x1 > $ye-$y0 ) {
// Width larger than height
$x1 = $this->rect->x + ($y1-$ye);
$y1 = $ye;
$y0 = $this->rect->y;
while( $x0 <= $xe ) {
$aImg->Line($x0,$y0,$x1,$y1);
$x0 += $this->linespacing;
$x1 += $this->linespacing;
}
$y0=$this->rect->y + ($x0-$xe);
$x0=$xe;
}
else {
// Height larger than width
$diff = $x0-$xe;
$y0 = $diff+$this->rect->y;
$x0 = $xe;
$x1 = $this->rect->x;
while( $y1 <= $ye ) {
$aImg->Line($x0,$y0,$x1,$y1);
$y1 += $this->linespacing;
$y0 += $this->linespacing;
}
$diff = $y1-$ye;
$y1 = $ye;
$x1 = $diff + $this->rect->x;
}
while( $y0 <= $ye ) {
$aImg->Line($x0,$y0,$x1,$y1);
$y0 += $this->linespacing;
$x1 += $this->linespacing;
}
}
}
//=====================================================================
// Class RectPatternLDiag
// Implements left diagonal pattern
//=====================================================================
class RectPatternLDiag extends RectPattern {
function RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
$this->linespacing = $aLineSpacing;
parent::RectPattern($aColor,$aWeight);
}
function DoPattern($aImg) {
// --------------------
// |\ \ \ \ \ |
// | \ \ \ \ \|
// | \ \ \ \ |
// |------------------|
$xe = $this->rect->xe;
$ye = $this->rect->ye;
$x0 = $this->rect->x + round($this->linespacing/2);
$y0 = $this->rect->ye;
$x1 = $this->rect->x;
$y1 = $this->rect->ye - round($this->linespacing/2);
while($x0<=$xe && $y1>=$this->rect->y) {
$aImg->Line($x0,$y0,$x1,$y1);
$x0 += $this->linespacing;
$y1 -= $this->linespacing;
}
if( $xe-$x1 > $ye-$this->rect->y ) {
// Width larger than height
$x1 = $this->rect->x + ($this->rect->y-$y1);
$y0=$ye; $y1=$this->rect->y;
while( $x0 <= $xe ) {
$aImg->Line($x0,$y0,$x1,$y1);
$x0 += $this->linespacing;
$x1 += $this->linespacing;
}
$y0=$this->rect->ye - ($x0-$xe);
$x0=$xe;
}
else {
// Height larger than width
$diff = $x0-$xe;
$y0 = $ye-$diff;
$x0 = $xe;
while( $y1 >= $this->rect->y ) {
$aImg->Line($x0,$y0,$x1,$y1);
$y0 -= $this->linespacing;
$y1 -= $this->linespacing;
}
$diff = $this->rect->y - $y1;
$x1 = $this->rect->x + $diff;
$y1 = $this->rect->y;
}
while( $y0 >= $this->rect->y ) {
$aImg->Line($x0,$y0,$x1,$y1);
$y0 -= $this->linespacing;
$x1 += $this->linespacing;
}
}
}
//=====================================================================
// Class RectPattern3DPlane
// Implements "3D" plane pattern
//=====================================================================
class RectPattern3DPlane extends RectPattern {
private $alpha=50; // Parameter that specifies the distance
// to "simulated" horizon in pixel from the
// top of the band. Specifies how fast the lines
// converge.
function RectPattern3DPlane($aColor="black",$aWeight=1) {
parent::RectPattern($aColor,$aWeight);
$this->SetDensity(10); // Slightly larger default
}
function SetHorizon($aHorizon) {
$this->alpha=$aHorizon;
}
function DoPattern($aImg) {
// "Fake" a nice 3D grid-effect.
$x0 = $this->rect->x + $this->rect->w/2;
$y0 = $this->rect->y;
$x1 = $x0;
$y1 = $this->rect->ye;
$x0_right = $x0;
$x1_right = $x1;
// BTW "apa" means monkey in Swedish but is really a shortform for
// "alpha+a" which was the labels I used on paper when I derived the
// geometric to get the 3D perspective right.
// $apa is the height of the bounding rectangle plus the distance to the
// artifical horizon (alpha)
$apa = $this->rect->h + $this->alpha;
// Three cases and three loops
// 1) The endpoint of the line ends on the bottom line
// 2) The endpoint ends on the side
// 3) Horizontal lines
// Endpoint falls on bottom line
$middle=$this->rect->x + $this->rect->w/2;
$dist=$this->linespacing;
$factor=$this->alpha /($apa);
while($x1>$this->rect->x) {
$aImg->Line($x0,$y0,$x1,$y1);
$aImg->Line($x0_right,$y0,$x1_right,$y1);
$x1 = $middle - $dist;
$x0 = $middle - $dist * $factor;
$x1_right = $middle + $dist;
$x0_right = $middle + $dist * $factor;
$dist += $this->linespacing;
}
// Endpoint falls on sides
$dist -= $this->linespacing;
$d=$this->rect->w/2;
$c = $apa - $d*$apa/$dist;
while( $x0>$this->rect->x ) {
$aImg->Line($x0,$y0,$this->rect->x,$this->rect->ye-$c);
$aImg->Line($x0_right,$y0,$this->rect->xe,$this->rect->ye-$c);
$dist += $this->linespacing;
$x0 = $middle - $dist * $factor;
$x1 = $middle - $dist;
$x0_right = $middle + $dist * $factor;
$c = $apa - $d*$apa/$dist;
}
// Horizontal lines
// They need some serious consideration since they are a function
// of perspective depth (alpha) and density (linespacing)
$x0=$this->rect->x;
$x1=$this->rect->xe;
$y=$this->rect->ye;
// The first line is drawn directly. Makes the loop below slightly
// more readable.
$aImg->Line($x0,$y,$x1,$y);
$hls = $this->linespacing;
// A correction factor for vertical "brick" line spacing to account for
// a) the difference in number of pixels hor vs vert
// b) visual apperance to make the first layer of "bricks" look more
// square.
$vls = $this->linespacing*0.6;
$ds = $hls*($apa-$vls)/$apa;
// Get the slope for the "perspective line" going from bottom right
// corner to top left corner of the "first" brick.
// Uncomment the following lines if you want to get a visual understanding
// of what this helpline does. BTW this mimics the way you would get the
// perspective right when drawing on paper.
/*
$x0 = $middle;
$y0 = $this->rect->ye;
$len=floor(($this->rect->ye-$this->rect->y)/$vls);
$x1 = $middle+round($len*$ds);
$y1 = $this->rect->ye-$len*$vls;
$aImg->PushColor("red");
$aImg->Line($x0,$y0,$x1,$y1);
$aImg->PopColor();
*/
$y -= $vls;
$k=($this->rect->ye-($this->rect->ye-$vls))/($middle-($middle-$ds));
$dist = $hls;
while( $y>$this->rect->y ) {
$aImg->Line($this->rect->x,$y,$this->rect->xe,$y);
$adj = $k*$dist/(1+$dist*$k/$apa);
if( $adj < 2 ) $adj=1;
$y = $this->rect->ye - round($adj);
$dist += $hls;
}
}
}
//=====================================================================
// Class RectPatternCross
// Vert/Hor crosses
//=====================================================================
class RectPatternCross extends RectPattern {
private $vert=null;
private $hor=null;
function RectPatternCross($aColor="black",$aWeight=1) {
parent::RectPattern($aColor,$aWeight);
$this->vert = new RectPatternVert($aColor,$aWeight);
$this->hor = new RectPatternHor($aColor,$aWeight);
}
function SetOrder($aDepth) {
$this->vert->SetOrder($aDepth);
$this->hor->SetOrder($aDepth);
}
function SetPos($aRect) {
parent::SetPos($aRect);
$this->vert->SetPos($aRect);
$this->hor->SetPos($aRect);
}
function SetDensity($aDens) {
$this->vert->SetDensity($aDens);
$this->hor->SetDensity($aDens);
}
function DoPattern($aImg) {
$this->vert->DoPattern($aImg);
$this->hor->DoPattern($aImg);
}
}
//=====================================================================
// Class RectPatternDiagCross
// Vert/Hor crosses
//=====================================================================
class RectPatternDiagCross extends RectPattern {
private $left=null;
private $right=null;
function RectPatternDiagCross($aColor="black",$aWeight=1) {
parent::RectPattern($aColor,$aWeight);
$this->right = new RectPatternRDiag($aColor,$aWeight);
$this->left = new RectPatternLDiag($aColor,$aWeight);
}
function SetOrder($aDepth) {
$this->left->SetOrder($aDepth);
$this->right->SetOrder($aDepth);
}
function SetPos($aRect) {
parent::SetPos($aRect);
$this->left->SetPos($aRect);
$this->right->SetPos($aRect);
}
function SetDensity($aDens) {
$this->left->SetDensity($aDens);
$this->right->SetDensity($aDens);
}
function DoPattern($aImg) {
$this->left->DoPattern($aImg);
$this->right->DoPattern($aImg);
}
}
//=====================================================================
// Class RectPatternFactory
// Factory class for rectangular pattern
//=====================================================================
class RectPatternFactory {
function RectPatternFactory() {
// Empty
}
function Create($aPattern,$aColor,$aWeight=1) {
switch($aPattern) {
case BAND_RDIAG:
$obj = new RectPatternRDiag($aColor,$aWeight);
break;
case BAND_LDIAG:
$obj = new RectPatternLDiag($aColor,$aWeight);
break;
case BAND_SOLID:
$obj = new RectPatternSolid($aColor,$aWeight);
break;
case BAND_VLINE:
$obj = new RectPatternVert($aColor,$aWeight);
break;
case BAND_HLINE:
$obj = new RectPatternHor($aColor,$aWeight);
break;
case BAND_3DPLANE:
$obj = new RectPattern3DPlane($aColor,$aWeight);
break;
case BAND_HVCROSS:
$obj = new RectPatternCross($aColor,$aWeight);
break;
case BAND_DIAGCROSS:
$obj = new RectPatternDiagCross($aColor,$aWeight);
break;
default:
JpGraphError::RaiseL(16003,$aPattern);
//(" Unknown pattern specification ($aPattern)");
}
return $obj;
}
}
//=====================================================================
// Class PlotBand
// Factory class which is used by the client.
// It is responsible for factoring the corresponding pattern
// concrete class.
//=====================================================================
class PlotBand {
public $depth; // Determine if band should be over or under the plots
private $prect=null;
private $dir, $min, $max;
function PlotBand($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) {
$f = new RectPatternFactory();
$this->prect = $f->Create($aPattern,$aColor,$aWeight);
if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) )
JpGraphError::RaiseL(16004);
//('Min value for plotband is larger than specified max value. Please correct.');
$this->dir = $aDir;
$this->min = $aMin;
$this->max = $aMax;
$this->depth=$aDepth;
}
// Set position. aRect contains absolute image coordinates
function SetPos($aRect) {
assert( $this->prect != null ) ;
$this->prect->SetPos($aRect);
}
function ShowFrame($aFlag=true) {
$this->prect->ShowFrame($aFlag);
}
// Set z-order. In front of pplot or in the back
function SetOrder($aDepth) {
$this->depth=$aDepth;
}
function SetDensity($aDens) {
$this->prect->SetDensity($aDens);
}
function GetDir() {
return $this->dir;
}
function GetMin() {
return $this->min;
}
function GetMax() {
return $this->max;
}
function PreStrokeAdjust($aGraph) {
// Nothing to do
}
// Display band
function Stroke($aImg,$aXScale,$aYScale) {
assert( $this->prect != null ) ;
if( $this->dir == HORIZONTAL ) {
if( $this->min === 'min' ) $this->min = $aYScale->GetMinVal();
if( $this->max === 'max' ) $this->max = $aYScale->GetMaxVal();
// Only draw the bar if it actually appears in the range
if ($this->min < $aYScale->GetMaxVal() && $this->max > $aYScale->GetMinVal()) {
// Trucate to limit of axis
$this->min = max($this->min, $aYScale->GetMinVal());
$this->max = min($this->max, $aYScale->GetMaxVal());
$x=$aXScale->scale_abs[0];
$y=$aYScale->Translate($this->max);
$width=$aXScale->scale_abs[1]-$aXScale->scale_abs[0]+1;
$height=abs($y-$aYScale->Translate($this->min))+1;
$this->prect->SetPos(new Rectangle($x,$y,$width,$height));
$this->prect->Stroke($aImg);
}
}
else { // VERTICAL
if( $this->min === 'min' ) $this->min = $aXScale->GetMinVal();
if( $this->max === 'max' ) $this->max = $aXScale->GetMaxVal();
// Only draw the bar if it actually appears in the range
if ($this->min < $aXScale->GetMaxVal() && $this->max > $aXScale->GetMinVal()) {
// Trucate to limit of axis
$this->min = max($this->min, $aXScale->GetMinVal());
$this->max = min($this->max, $aXScale->GetMaxVal());
$y=$aYScale->scale_abs[1];
$x=$aXScale->Translate($this->min);
$height=abs($aYScale->scale_abs[1]-$aYScale->scale_abs[0]);
$width=abs($x-$aXScale->Translate($this->max));
$this->prect->SetPos(new Rectangle($x,$y,$width,$height));
$this->prect->Stroke($aImg);
}
}
}
}
?>

View File

@ -1,482 +0,0 @@
<?php
//=======================================================================
// File: JPGRAPH_PLOTMARK.PHP
// Description: Class file. Handles plotmarks
// Created: 2003-03-21
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_plotmark.inc 209 2005-09-26 17:23:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
//========================================================================
// CLASS ImgData
// Description: Base class for all image data classes that contains the
// real image data.
//========================================================================
class ImgData {
var $name = ''; // Each subclass gives a name
var $an = array(); // Data array names
var $colors = array(); // Available colors
var $index = array(); // Index for colors
var $maxidx = 0 ; // Max color index
var $anchor_x=0.5, $anchor_y=0.5 ; // Where is the center of the image
// Create a GD image from the data and return a GD handle
function GetImg($aMark,$aIdx) {
$n = $this->an[$aMark];
if( is_string($aIdx) ) {
if( !in_array($aIdx,$this->colors) ) {
JpGraphError::Raise('This marker "'.($this->name).'" does not exist in color: '.$aIdx);
die();
}
$idx = $this->index[$aIdx];
}
elseif( !is_integer($aIdx) ||
(is_integer($aIdx) && $aIdx > $this->maxidx ) ) {
JpGraphError::Raise('Mark color index too large for marker "'.($this->name).'"');
}
else
$idx = $aIdx ;
return Image::CreateFromString(base64_decode($this->{$n}[$idx][1]));
}
function GetAnchor() {
return array($this->anchor_x,$this->anchor_y);
}
}
// Keep a global flag cache to reduce memory usage
$_gFlagCache=array(
1 => null,
2 => null,
3 => null,
4 => null,
);
// Only supposed to b called as statics
class FlagCache {
function GetFlagImgByName($aSize,$aName) {
global $_gFlagCache;
require_once('jpgraph_flags.php');
if( $_gFlagCache[$aSize] === null ) {
$_gFlagCache[$aSize] =& new FlagImages($aSize);
}
$f =& $_gFlagCache[$aSize];
$idx = $f->GetIdxByName($aName,$aFullName);
return $f->GetImgByIdx($idx);
}
}
//===================================================
// CLASS PlotMark
// Description: Handles the plot marks in graphs
//===================================================
class PlotMark {
var $title, $show=true;
var $type,$weight=1;
var $color="black", $width=4, $fill_color="blue";
var $yvalue,$xvalue='',$csimtarget,$csimalt,$csimareas;
var $iFormatCallback="";
var $iFormatCallback2="";
var $markimg='',$iScale=1.0;
var $oldfilename='',$iFileName='';
var $imgdata_balls = null;
var $imgdata_diamonds = null;
var $imgdata_squares = null;
var $imgdata_bevels = null;
var $imgdata_stars = null;
var $imgdata_pushpins = null;
//--------------
// CONSTRUCTOR
function PlotMark() {
$this->title = new Text();
$this->title->Hide();
$this->csimareas = '';
$this->csimalt = '';
$this->type=-1;
}
//---------------
// PUBLIC METHODS
function SetType($aType,$aFileName='',$aScale=1.0) {
$this->type = $aType;
if( $aType == MARK_IMG && $aFileName=='' ) {
JpGraphError::Raise('A filename must be specified if you set the mark type to MARK_IMG.');
}
$this->iFileName = $aFileName;
$this->iScale = $aScale;
}
function SetCallback($aFunc) {
$this->iFormatCallback = $aFunc;
}
function SetCallbackYX($aFunc) {
$this->iFormatCallback2 = $aFunc;
}
function GetType() {
return $this->type;
}
function SetColor($aColor) {
$this->color=$aColor;
}
function SetFillColor($aFillColor) {
$this->fill_color = $aFillColor;
}
function SetWeight($aWeight) {
$this->weight = $aWeight;
}
// Synonym for SetWidth()
function SetSize($aWidth) {
$this->width=$aWidth;
}
function SetWidth($aWidth) {
$this->width=$aWidth;
}
function SetDefaultWidth() {
switch( $this->type ) {
case MARK_CIRCLE:
case MARK_FILLEDCIRCLE:
$this->width=4;
break;
default:
$this->width=7;
}
}
function GetWidth() {
return $this->width;
}
function Hide($aHide=true) {
$this->show = !$aHide;
}
function Show($aShow=true) {
$this->show = $aShow;
}
function SetCSIMAltVal($aY,$aX='') {
$this->yvalue=$aY;
$this->xvalue=$aX;
}
function SetCSIMTarget($aTarget) {
$this->csimtarget=$aTarget;
}
function SetCSIMAlt($aAlt) {
$this->csimalt=$aAlt;
}
function GetCSIMAreas(){
return $this->csimareas;
}
function AddCSIMPoly($aPts) {
$coords = round($aPts[0]).", ".round($aPts[1]);
$n = count($aPts)/2;
for( $i=1; $i < $n; ++$i){
$coords .= ", ".round($aPts[2*$i]).", ".round($aPts[2*$i+1]);
}
$this->csimareas="";
if( !empty($this->csimtarget) ) {
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtarget."\"";
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\"";
}
$this->csimareas .= " alt=\"$tmp\" />\n";
}
}
function AddCSIMCircle($x,$y,$r) {
$x = round($x); $y=round($y); $r=round($r);
$this->csimareas="";
if( !empty($this->csimtarget) ) {
$this->csimareas .= "<area shape=\"circle\" coords=\"$x,$y,$r\" href=\"".$this->csimtarget."\"";
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\"";
}
$this->csimareas .= " alt=\"$tmp\" />\n";
}
}
function Stroke($img,$x,$y) {
if( !$this->show ) return;
if( $this->iFormatCallback != '' || $this->iFormatCallback2 != '' ) {
if( $this->iFormatCallback != '' ) {
$f = $this->iFormatCallback;
list($width,$color,$fcolor) = call_user_func($f,$this->yvalue);
$filename = $this->iFileName;
$imgscale = $this->iScale;
}
else {
$f = $this->iFormatCallback2;
list($width,$color,$fcolor,$filename,$imgscale) = call_user_func($f,$this->yvalue,$this->xvalue);
if( $filename=="" ) $filename = $this->iFileName;
if( $imgscale=="" ) $imgscale = $this->iScale;
}
if( $width=="" ) $width = $this->width;
if( $color=="" ) $color = $this->color;
if( $fcolor=="" ) $fcolor = $this->fill_color;
}
else {
$fcolor = $this->fill_color;
$color = $this->color;
$width = $this->width;
$filename = $this->iFileName;
$imgscale = $this->iScale;
}
if( $this->type == MARK_IMG ||
($this->type >= MARK_FLAG1 && $this->type <= MARK_FLAG4 ) ||
$this->type >= MARK_IMG_PUSHPIN ) {
// Note: For the builtin images we use the "filename" parameter
// to denote the color
$anchor_x = 0.5;
$anchor_y = 0.5;
switch( $this->type ) {
case MARK_FLAG1:
case MARK_FLAG2:
case MARK_FLAG3:
case MARK_FLAG4:
$this->markimg = FlagCache::GetFlagImgByName($this->type-MARK_FLAG1+1,$filename);
break;
case MARK_IMG :
// Load an image and use that as a marker
// Small optimization, if we have already read an image don't
// waste time reading it again.
if( $this->markimg == '' || !($this->oldfilename === $filename) ) {
$this->markimg = Graph::LoadBkgImage('',$filename);
$this->oldfilename = $filename ;
}
break;
case MARK_IMG_PUSHPIN:
case MARK_IMG_SPUSHPIN:
case MARK_IMG_LPUSHPIN:
if( $this->imgdata_pushpins == null ) {
require_once 'imgdata_pushpins.inc';
$this->imgdata_pushpins = new ImgData_PushPins();
}
$this->markimg = $this->imgdata_pushpins->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_pushpins->GetAnchor();
break;
case MARK_IMG_SQUARE:
if( $this->imgdata_squares == null ) {
require_once 'imgdata_squares.inc';
$this->imgdata_squares = new ImgData_Squares();
}
$this->markimg = $this->imgdata_squares->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_squares->GetAnchor();
break;
case MARK_IMG_STAR:
if( $this->imgdata_stars == null ) {
require_once 'imgdata_stars.inc';
$this->imgdata_stars = new ImgData_Stars();
}
$this->markimg = $this->imgdata_stars->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_stars->GetAnchor();
break;
case MARK_IMG_BEVEL:
if( $this->imgdata_bevels == null ) {
require_once 'imgdata_bevels.inc';
$this->imgdata_bevels = new ImgData_Bevels();
}
$this->markimg = $this->imgdata_bevels->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_bevels->GetAnchor();
break;
case MARK_IMG_DIAMOND:
if( $this->imgdata_diamonds == null ) {
require_once 'imgdata_diamonds.inc';
$this->imgdata_diamonds = new ImgData_Diamonds();
}
$this->markimg = $this->imgdata_diamonds->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_diamonds->GetAnchor();
break;
case MARK_IMG_BALL:
case MARK_IMG_SBALL:
case MARK_IMG_MBALL:
case MARK_IMG_LBALL:
if( $this->imgdata_balls == null ) {
require_once 'imgdata_balls.inc';
$this->imgdata_balls = new ImgData_Balls();
}
$this->markimg = $this->imgdata_balls->GetImg($this->type,$filename);
list($anchor_x,$anchor_y) = $this->imgdata_balls->GetAnchor();
break;
}
$w = $img->GetWidth($this->markimg);
$h = $img->GetHeight($this->markimg);
$dw = round($imgscale * $w );
$dh = round($imgscale * $h );
// Do potential rotation
list($x,$y) = $img->Rotate($x,$y);
$dx = round($x-$dw*$anchor_x);
$dy = round($y-$dh*$anchor_y);
$this->width = max($dx,$dy);
$img->Copy($this->markimg,$dx,$dy,0,0,$dw,$dh,$w,$h);
if( !empty($this->csimtarget) ) {
$this->csimareas = "<area shape=\"rect\" coords=\"".
$dx.','.$dy.','.round($dx+$dw).','.round($dy+$dh).'" '.
"href=\"".$this->csimtarget."\"";
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\"";
}
$this->csimareas .= " alt=\"$tmp\" />\n";
}
// Stroke title
$this->title->Align("center","top");
$this->title->Stroke($img,$x,$y+round($dh/2));
return;
}
$weight = $this->weight;
$dx=round($width/2,0);
$dy=round($width/2,0);
$pts=0;
switch( $this->type ) {
case MARK_SQUARE:
$c[]=$x-$dx;$c[]=$y-$dy;
$c[]=$x+$dx;$c[]=$y-$dy;
$c[]=$x+$dx;$c[]=$y+$dy;
$c[]=$x-$dx;$c[]=$y+$dy;
$c[]=$x-$dx;$c[]=$y-$dy;
$pts=5;
break;
case MARK_UTRIANGLE:
++$dx;++$dy;
$c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx
$c[]=$x;$c[]=$y-0.87*$dy;
$c[]=$x+$dx;$c[]=$y+0.87*$dy;
$c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx
$pts=4;
break;
case MARK_DTRIANGLE:
++$dx;++$dy;
$c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx
$c[]=$x-$dx;$c[]=$y-0.87*$dy;
$c[]=$x+$dx;$c[]=$y-0.87*$dy;
$c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx
$pts=4;
break;
case MARK_DIAMOND:
$c[]=$x;$c[]=$y+$dy;
$c[]=$x-$dx;$c[]=$y;
$c[]=$x;$c[]=$y-$dy;
$c[]=$x+$dx;$c[]=$y;
$c[]=$x;$c[]=$y+$dy;
$pts=5;
break;
case MARK_LEFTTRIANGLE:
$c[]=$x;$c[]=$y;
$c[]=$x;$c[]=$y+2*$dy;
$c[]=$x+$dx*2;$c[]=$y;
$c[]=$x;$c[]=$y;
$pts=4;
break;
case MARK_RIGHTTRIANGLE:
$c[]=$x-$dx*2;$c[]=$y;
$c[]=$x;$c[]=$y+2*$dy;
$c[]=$x;$c[]=$y;
$c[]=$x-$dx*2;$c[]=$y;
$pts=4;
break;
case MARK_FLASH:
$dy *= 2;
$c[]=$x+$dx/2; $c[]=$y-$dy;
$c[]=$x-$dx+$dx/2; $c[]=$y+$dy*0.7-$dy;
$c[]=$x+$dx/2; $c[]=$y+$dy*1.3-$dy;
$c[]=$x-$dx+$dx/2; $c[]=$y+2*$dy-$dy;
$img->SetLineWeight($weight);
$img->SetColor($color);
$img->Polygon($c);
$img->SetLineWeight(1);
$this->AddCSIMPoly($c);
break;
}
if( $pts>0 ) {
$this->AddCSIMPoly($c);
$img->SetLineWeight($weight);
$img->SetColor($fcolor);
$img->FilledPolygon($c);
$img->SetColor($color);
$img->Polygon($c);
$img->SetLineWeight(1);
}
elseif( $this->type==MARK_CIRCLE ) {
$img->SetColor($color);
$img->Circle($x,$y,$width);
$this->AddCSIMCircle($x,$y,$width);
}
elseif( $this->type==MARK_FILLEDCIRCLE ) {
$img->SetColor($fcolor);
$img->FilledCircle($x,$y,$width);
$img->SetColor($color);
$img->Circle($x,$y,$width);
$this->AddCSIMCircle($x,$y,$width);
}
elseif( $this->type==MARK_CROSS ) {
// Oversize by a pixel to match the X
$img->SetColor($color);
$img->SetLineWeight($weight);
$img->Line($x,$y+$dy+1,$x,$y-$dy-1);
$img->Line($x-$dx-1,$y,$x+$dx+1,$y);
$this->AddCSIMCircle($x,$y,$dx);
}
elseif( $this->type==MARK_X ) {
$img->SetColor($color);
$img->SetLineWeight($weight);
$img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy);
$img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy);
$this->AddCSIMCircle($x,$y,$dx+$dy);
}
elseif( $this->type==MARK_STAR ) {
$img->SetColor($color);
$img->SetLineWeight($weight);
$img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy);
$img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy);
// Oversize by a pixel to match the X
$img->Line($x,$y+$dy+1,$x,$y-$dy-1);
$img->Line($x-$dx-1,$y,$x+$dx+1,$y);
$this->AddCSIMCircle($x,$y,$dx+$dy);
}
// Stroke title
$this->title->Align("center","center");
$this->title->Stroke($img,$x,$y);
}
} // Class
?>

View File

@ -1,847 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_POLAR.PHP
// Description: Polar plot extension for JpGraph
// Created: 2003-02-02
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_polar.php 488 2006-02-04 12:26:03Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
require_once ('jpgraph_plotmark.inc.php');
require_once "jpgraph_log.php";
DEFINE('POLAR_360',1);
DEFINE('POLAR_180',2);
//
// Note. Don't attempt to make sense of this code.
// In order not to have to be able to inherit the scaling code
// from the main graph package we have had to make some "tricks" since
// the original scaling and axis was not designed to do what is
// required here.
// There were two option. 1: Re-implement everything and get a clean design
// and 2: do some "small" trickery and be able to inherit most of
// the functionlity from the main graph package.
// We choose 2: here in order to save some time.
//
//--------------------------------------------------------------------------
// class PolarPlot
//--------------------------------------------------------------------------
class PolarPlot {
public $line_style='solid',$mark;
public $legendcsimtarget='';
public $legendcsimalt='';
public $legend="";
public $csimtargets=array(); // Array of targets for CSIM
public $csimareas=""; // Resultant CSIM area tags
public $csimalts=null; // ALT:s for corresponding target
public $scale=null;
private $numpoints=0;
private $iColor='navy',$iFillColor='';
private $iLineWeight=1;
private $coord=null;
function PolarPlot($aData) {
$n = count($aData);
if( $n & 1 ) {
JpGraphError::RaiseL(17001);
//('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).');
}
$this->numpoints = $n/2;
$this->coord = $aData;
$this->mark = new PlotMark();
}
function SetWeight($aWeight) {
$this->iLineWeight = $aWeight;
}
function SetColor($aColor){
$this->iColor = $aColor;
}
function SetFillColor($aColor){
$this->iFillColor = $aColor;
}
function Max() {
$m = $this->coord[1];
$i=1;
while( $i < $this->numpoints ) {
$m = max($m,$this->coord[2*$i+1]);
++$i;
}
return $m;
}
// Set href targets for CSIM
function SetCSIMTargets($aTargets,$aAlts=null) {
$this->csimtargets=$aTargets;
$this->csimalts=$aAlts;
}
// Get all created areas
function GetCSIMareas() {
return $this->csimareas;
}
function SetLegend($aLegend,$aCSIM="",$aCSIMAlt="") {
$this->legend = $aLegend;
$this->legendcsimtarget = $aCSIM;
$this->legendcsimalt = $aCSIMAlt;
}
// Private methods
function Legend($aGraph) {
$color = $this->iColor ;
if( $this->legend != "" ) {
if( $this->iFillColor!='' ) {
$color = $this->iFillColor;
$aGraph->legend->Add($this->legend,$color,$this->mark,0,
$this->legendcsimtarget,$this->legendcsimalt);
}
else {
$aGraph->legend->Add($this->legend,$color,$this->mark,$this->line_style,
$this->legendcsimtarget,$this->legendcsimalt);
}
}
}
function Stroke($img,$scale) {
$i=0;
$p=array();
$this->csimareas='';
while($i < $this->numpoints) {
list($x1,$y1) = $scale->PTranslate($this->coord[2*$i],$this->coord[2*$i+1]);
$p[2*$i] = $x1;
$p[2*$i+1] = $y1;
if( isset($this->csimtargets[$i]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$i]);
$this->mark->SetCSIMAlt($this->csimalts[$i]);
$this->mark->SetCSIMAltVal($this->coord[2*$i], $this->coord[2*$i+1]);
$this->mark->Stroke($img,$x1,$y1);
$this->csimareas .= $this->mark->GetCSIMAreas();
}
else
$this->mark->Stroke($img,$x1,$y1);
++$i;
}
if( $this->iFillColor != '' ) {
$img->SetColor($this->iFillColor);
$img->FilledPolygon($p);
}
$img->SetLineWeight($this->iLineWeight);
$img->SetColor($this->iColor);
$img->Polygon($p,$this->iFillColor!='');
}
}
//--------------------------------------------------------------------------
// class PolarAxis
//--------------------------------------------------------------------------
class PolarAxis extends Axis {
private $angle_step=15,$angle_color='lightgray',$angle_label_color='black';
private $angle_fontfam=FF_FONT1,$angle_fontstyle=FS_NORMAL,$angle_fontsize=10;
private $angle_fontcolor = 'navy';
private $gridminor_color='lightgray',$gridmajor_color='lightgray';
private $show_minor_grid = false, $show_major_grid = true ;
private $show_angle_mark=true, $show_angle_grid=true, $show_angle_label=true;
private $angle_tick_len=3, $angle_tick_len2=3, $angle_tick_color='black';
private $show_angle_tick=true;
private $radius_tick_color='black';
function PolarAxis($img,$aScale) {
parent::Axis($img,$aScale);
}
function ShowAngleDegreeMark($aFlg=true) {
$this->show_angle_mark = $aFlg;
}
function SetAngleStep($aStep) {
$this->angle_step=$aStep;
}
function HideTicks($aFlg=true,$aAngleFlg=true) {
parent::HideTicks($aFlg,$aFlg);
$this->show_angle_tick = !$aAngleFlg;
}
function ShowAngleLabel($aFlg=true) {
$this->show_angle_label = $aFlg;
}
function ShowGrid($aMajor=true,$aMinor=false,$aAngle=true) {
$this->show_minor_grid = $aMinor;
$this->show_major_grid = $aMajor;
$this->show_angle_grid = $aAngle ;
}
function SetAngleFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=10) {
$this->angle_fontfam = $aFontFam;
$this->angle_fontstyle = $aFontStyle;
$this->angle_fontsize = $aFontSize;
}
function SetColor($aColor,$aRadColor='',$aAngleColor='') {
if( $aAngleColor == '' )
$aAngleColor=$aColor;
parent::SetColor($aColor,$aRadColor);
$this->angle_fontcolor = $aAngleColor;
}
function SetGridColor($aMajorColor,$aMinorColor='',$aAngleColor='') {
if( $aMinorColor == '' )
$aMinorColor = $aMajorColor;
if( $aAngleColor == '' )
$aAngleColor = $aMajorColor;
$this->gridminor_color = $aMinorColor;
$this->gridmajor_color = $aMajorColor;
$this->angle_color = $aAngleColor;
}
function SetTickColors($aRadColor,$aAngleColor='') {
$this->radius_tick_color = $aRadColor;
$this->angle_tick_color = $aAngleColor;
}
// Private methods
function StrokeGrid($pos) {
$x = round($this->img->left_margin + $this->img->plotwidth/2);
$this->scale->ticks->Stroke($this->img,$this->scale,$pos);
// Stroke the minor arcs
$pmin = array();
$p = $this->scale->ticks->ticks_pos;
$n = count($p);
$i = 0;
$this->img->SetColor($this->gridminor_color);
while( $i < $n ) {
$r = $p[$i]-$x+1;
$pmin[]=$r;
if( $this->show_minor_grid ) {
$this->img->Circle($x,$pos,$r);
}
$i++;
}
$limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ;
while( $r < $limit ) {
$off = $r;
$i=1;
$r = $off + round($p[$i]-$x+1);
while( $r < $limit && $i < $n ) {
$r = $off+$p[$i]-$x;
$pmin[]=$r;
if( $this->show_minor_grid ) {
$this->img->Circle($x,$pos,$r);
}
$i++;
}
}
// Stroke the major arcs
if( $this->show_major_grid ) {
// First determine how many minor step on
// every major step. We have recorded the minor radius
// in pmin and use these values. This is done in order
// to avoid rounding errors if we were to recalculate the
// different major radius.
$pmaj = $this->scale->ticks->maj_ticks_pos;
$p = $this->scale->ticks->ticks_pos;
if( $this->scale->name == 'lin' ) {
$step=round(($pmaj[1] - $pmaj[0])/($p[1] - $p[0]));
}
else {
$step=9;
}
$n = round(count($pmin)/$step);
$i = 0;
$this->img->SetColor($this->gridmajor_color);
$limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ;
$off = $r;
$i=0;
$r = $pmin[$i*$step];
while( $r < $limit && $i < $n ) {
$r = $pmin[$i*$step];
$this->img->Circle($x,$pos,$r);
$i++;
}
}
// Draw angles
if( $this->show_angle_grid ) {
$this->img->SetColor($this->angle_color);
$d = max($this->img->plotheight,$this->img->plotwidth)*1.4 ;
$a = 0;
$p = $this->scale->ticks->ticks_pos;
$start_radius = $p[1]-$x;
while( $a < 360 ) {
if( $a == 90 || $a == 270 ) {
// Make sure there are no rounding problem with
// exactly vertical lines
$this->img->Line($x+$start_radius*cos($a/180*M_PI)+1,
$pos-$start_radius*sin($a/180*M_PI),
$x+$start_radius*cos($a/180*M_PI)+1,
$pos-$d*sin($a/180*M_PI));
}
else {
$this->img->Line($x+$start_radius*cos($a/180*M_PI)+1,
$pos-$start_radius*sin($a/180*M_PI),
$x+$d*cos($a/180*M_PI),
$pos-$d*sin($a/180*M_PI));
}
$a += $this->angle_step;
}
}
}
function StrokeAngleLabels($pos,$type) {
if( !$this->show_angle_label )
return;
$x0 = round($this->img->left_margin+$this->img->plotwidth/2)+1;
$d = max($this->img->plotwidth,$this->img->plotheight)*1.42;
$a = $this->angle_step;
$t = new Text();
$t->SetColor($this->angle_fontcolor);
$t->SetFont($this->angle_fontfam,$this->angle_fontstyle,$this->angle_fontsize);
$xright = $this->img->width - $this->img->right_margin;
$ytop = $this->img->top_margin;
$xleft = $this->img->left_margin;
$ybottom = $this->img->height - $this->img->bottom_margin;
$ha = 'left';
$va = 'center';
$w = $this->img->plotwidth/2;
$h = $this->img->plotheight/2;
$xt = $x0; $yt = $pos;
$margin=5;
$tl = $this->angle_tick_len ; // Outer len
$tl2 = $this->angle_tick_len2 ; // Interior len
$this->img->SetColor($this->angle_tick_color);
$rot90 = $this->img->a == 90 ;
if( $type == POLAR_360 ) {
$ca1 = atan($h/$w)/M_PI*180;
$ca2 = 180-$ca1;
$ca3 = $ca1+180;
$ca4 = 360-$ca1;
$end = 360;
while( $a < $end ) {
$ca = cos($a/180*M_PI);
$sa = sin($a/180*M_PI);
$x = $d*$ca;
$y = $d*$sa;
$xt=1000;$yt=1000;
if( $a <= $ca1 || $a >= $ca4 ) {
$yt = $pos - $w * $y/$x;
$xt = $xright + $margin;
if( $rot90 ) {
$ha = 'center';
$va = 'top';
}
else {
$ha = 'left';
$va = 'center';
}
$x1=$xright-$tl2; $x2=$xright+$tl;
$y1=$y2=$yt;
}
elseif( $a > $ca1 && $a < $ca2 ) {
$xt = $x0 + $h * $x/$y;
$yt = $ytop - $margin;
if( $rot90 ) {
$ha = 'left';
$va = 'center';
}
else {
$ha = 'center';
$va = 'bottom';
}
$y1=$ytop+$tl2;$y2=$ytop-$tl;
$x1=$x2=$xt;
}
elseif( $a >= $ca2 && $a <= $ca3 ) {
$yt = $pos + $w * $y/$x;
$xt = $xleft - $margin;
if( $rot90 ) {
$ha = 'center';
$va = 'bottom';
}
else {
$ha = 'right';
$va = 'center';
}
$x1=$xleft+$tl2;$x2=$xleft-$tl;
$y1=$y2=$yt;
}
else {
$xt = $x0 - $h * $x/$y;
$yt = $ybottom + $margin;
if( $rot90 ) {
$ha = 'right';
$va = 'center';
}
else {
$ha = 'center';
$va = 'top';
}
$y1=$ybottom-$tl2;$y2=$ybottom+$tl;
$x1=$x2=$xt;
}
if( $a != 0 && $a != 180 ) {
$t->Align($ha,$va);
if( $this->show_angle_mark )
$a .= '°';
$t->Set($a);
$t->Stroke($this->img,$xt,$yt);
if( $this->show_angle_tick )
$this->img->Line($x1,$y1,$x2,$y2);
}
$a += $this->angle_step;
}
}
else {
// POLAR_HALF
$ca1 = atan($h/$w*2)/M_PI*180;
$ca2 = 180-$ca1;
$end = 180;
while( $a < $end ) {
$ca = cos($a/180*M_PI);
$sa = sin($a/180*M_PI);
$x = $d*$ca;
$y = $d*$sa;
if( $a <= $ca1 ) {
$yt = $pos - $w * $y/$x;
$xt = $xright + $margin;
if( $rot90 ) {
$ha = 'center';
$va = 'top';
}
else {
$ha = 'left';
$va = 'center';
}
$x1=$xright-$tl2; $x2=$xright+$tl;
$y1=$y2=$yt;
}
elseif( $a > $ca1 && $a < $ca2 ) {
$xt = $x0 + 2*$h * $x/$y;
$yt = $ytop - $margin;
if( $rot90 ) {
$ha = 'left';
$va = 'center';
}
else {
$ha = 'center';
$va = 'bottom';
}
$y1=$ytop+$tl2;$y2=$ytop-$tl;
$x1=$x2=$xt;
}
elseif( $a >= $ca2 ) {
$yt = $pos + $w * $y/$x;
$xt = $xleft - $margin;
if( $rot90 ) {
$ha = 'center';
$va = 'bottom';
}
else {
$ha = 'right';
$va = 'center';
}
$x1=$xleft+$tl2;$x2=$xleft-$tl;
$y1=$y2=$yt;
}
$t->Align($ha,$va);
if( $this->show_angle_mark )
$a .= '°';
$t->Set($a);
$t->Stroke($this->img,$xt,$yt);
if( $this->show_angle_tick )
$this->img->Line($x1,$y1,$x2,$y2);
$a += $this->angle_step;
}
}
}
function Stroke($pos,$dummy=true) {
$this->img->SetLineWeight($this->weight);
$this->img->SetColor($this->color);
$this->img->SetFont($this->font_family,$this->font_style,$this->font_size);
if( !$this->hide_line )
$this->img->FilledRectangle($this->img->left_margin,$pos,
$this->img->width-$this->img->right_margin,$pos+$this->weight-1);
$y=$pos+$this->img->GetFontHeight()+$this->title_margin+$this->title->margin;
if( $this->title_adjust=="high" )
$this->title->SetPos($this->img->width-$this->img->right_margin,$y,"right","top");
elseif( $this->title_adjust=="middle" || $this->title_adjust=="center" )
$this->title->SetPos(($this->img->width-$this->img->left_margin-
$this->img->right_margin)/2+$this->img->left_margin,
$y,"center","top");
elseif($this->title_adjust=="low")
$this->title->SetPos($this->img->left_margin,$y,"left","top");
else {
JpGraphError::RaiseL(17002,$this->title_adjust);
//('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')');
}
if (!$this->hide_labels) {
$this->StrokeLabels($pos,false);
}
$this->img->SetColor($this->radius_tick_color);
$this->scale->ticks->Stroke($this->img,$this->scale,$pos);
//
// Mirror the positions for the left side of the scale
//
$mid = 2*($this->img->left_margin+$this->img->plotwidth/2);
$n = count($this->scale->ticks->ticks_pos);
$i=0;
while( $i < $n ) {
$this->scale->ticks->ticks_pos[$i] =
$mid-$this->scale->ticks->ticks_pos[$i] ;
++$i;
}
$n = count($this->scale->ticks->maj_ticks_pos);
$i=0;
while( $i < $n ) {
$this->scale->ticks->maj_ticks_pos[$i] =
$mid-$this->scale->ticks->maj_ticks_pos[$i] ;
++$i;
}
$n = count($this->scale->ticks->maj_ticklabels_pos);
$i=1;
while( $i < $n ) {
$this->scale->ticks->maj_ticklabels_pos[$i] =
$mid-$this->scale->ticks->maj_ticklabels_pos[$i] ;
++$i;
}
// Draw the left side of the scale
$n = count($this->scale->ticks->ticks_pos);
$yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMinTickAbsSize();
// Minor ticks
if( ! $this->scale->ticks->supress_minor_tickmarks ) {
$i=1;
while( $i < $n/2 ) {
$x = round($this->scale->ticks->ticks_pos[$i]) ;
$this->img->Line($x,$pos,$x,$yu);
++$i;
}
}
$n = count($this->scale->ticks->maj_ticks_pos);
$yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMajTickAbsSize();
// Major ticks
if( ! $this->scale->ticks->supress_tickmarks ) {
$i=1;
while( $i < $n/2 ) {
$x = round($this->scale->ticks->maj_ticks_pos[$i]) ;
$this->img->Line($x,$pos,$x,$yu);
++$i;
}
}
if (!$this->hide_labels) {
$this->StrokeLabels($pos,false);
}
$this->title->Stroke($this->img);
}
}
class PolarScale extends LinearScale {
private $graph;
function PolarScale($aMax=0,$graph) {
parent::LinearScale(0,$aMax,'x');
$this->graph = $graph;
}
function _Translate($v) {
return parent::Translate($v);
}
function PTranslate($aAngle,$aRad) {
$m = $this->scale[1];
$w = $this->graph->img->plotwidth/2;
$aRad = $aRad/$m*$w;
$x = cos( $aAngle/180 * M_PI ) * $aRad;
$y = sin( $aAngle/180 * M_PI ) * $aRad;
$x += $this->_Translate(0);
if( $this->graph->iType == POLAR_360 ) {
$y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y;
}
else {
$y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y;
}
return array($x,$y);
}
}
class PolarLogScale extends LogScale {
private $graph;
function PolarLogScale($aMax=1,$graph) {
parent::LogScale(0,$aMax,'x');
$this->graph = $graph;
$this->ticks->SetLabelLogType(LOGLABELS_MAGNITUDE);
}
function PTranslate($aAngle,$aRad) {
if( $aRad == 0 )
$aRad = 1;
$aRad = log10($aRad);
$m = $this->scale[1];
$w = $this->graph->img->plotwidth/2;
$aRad = $aRad/$m*$w;
$x = cos( $aAngle/180 * M_PI ) * $aRad;
$y = sin( $aAngle/180 * M_PI ) * $aRad;
$x += $w+$this->graph->img->left_margin;//$this->_Translate(0);
if( $this->graph->iType == POLAR_360 ) {
$y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y;
}
else {
$y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y;
}
return array($x,$y);
}
}
class PolarGraph extends Graph {
public $scale;
public $axis;
public $iType=POLAR_360;
function PolarGraph($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) {
parent::Graph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline) ;
$this->SetDensity(TICKD_DENSE);
$this->SetBox();
$this->SetMarginColor('white');
}
function SetDensity($aDense) {
$this->SetTickDensity(TICKD_NORMAL,$aDense);
}
function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) {
$adj = ($this->img->height - $this->img->width)/2;
$this->SetAngle(90);
$this->img->SetMargin($lm-$adj,$rm-$adj,$tm+$adj,$bm+$adj);
$this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2));
$this->axis->SetLabelAlign('right','center');
//JpGraphError::Raise('Set90AndMargin() is not supported for polar graphs.');
}
function SetScale($aScale,$rmax=0,$dummy1=1,$dummy2=1,$dummy3=1) {
if( $aScale == 'lin' )
$this->scale = new PolarScale($rmax,$this);
elseif( $aScale == 'log' ) {
$this->scale = new PolarLogScale($rmax,$this);
}
else {
JpGraphError::RaiseL(17004);//('Unknown scale type for polar graph. Must be "lin" or "log"');
}
$this->axis = new PolarAxis($this->img,$this->scale);
$this->SetMargin(40,40,50,40);
}
function SetType($aType) {
$this->iType = $aType;
}
function SetPlotSize($w,$h) {
$this->SetMargin(($this->img->width-$w)/2,($this->img->width-$w)/2,
($this->img->height-$h)/2,($this->img->height-$h)/2);
}
// Private methods
function GetPlotsMax() {
$n = count($this->plots);
$m = $this->plots[0]->Max();
$i=1;
while($i < $n) {
$m = max($this->plots[$i]->Max(),$m);
++$i;
}
return $m;
}
function Stroke($aStrokeFileName="") {
// Start by adjusting the margin so that potential titles will fit.
$this->AdjustMarginsForTitles();
// If the filename is the predefined value = '_csim_special_'
// we assume that the call to stroke only needs to do enough
// to correctly generate the CSIM maps.
// We use this variable to skip things we don't strictly need
// to do to generate the image map to improve performance
// a best we can. Therefor you will see a lot of tests !$_csim in the
// code below.
$_csim = ($aStrokeFileName===_CSIM_SPECIALFILE);
// We need to know if we have stroked the plot in the
// GetCSIMareas. Otherwise the CSIM hasn't been generated
// and in the case of GetCSIM called before stroke to generate
// CSIM without storing an image to disk GetCSIM must call Stroke.
$this->iHasStroked = true;
//Check if we should autoscale axis
if( !$this->scale->IsSpecified() && count($this->plots)>0 ) {
$max = $this->GetPlotsMax();
$t1 = $this->img->plotwidth;
$this->img->plotwidth /= 2;
$t2 = $this->img->left_margin;
$this->img->left_margin += $this->img->plotwidth+1;
$this->scale->AutoScale($this->img,0,$max,
$this->img->plotwidth/$this->xtick_factor/2);
$this->img->plotwidth = $t1;
$this->img->left_margin = $t2;
}
else {
// The tick calculation will use the user suplied min/max values to determine
// the ticks. If auto_ticks is false the exact user specifed min and max
// values will be used for the scale.
// If auto_ticks is true then the scale might be slightly adjusted
// so that the min and max values falls on an even major step.
//$min = 0;
$max = $this->scale->scale[1];
$t1 = $this->img->plotwidth;
$this->img->plotwidth /= 2;
$t2 = $this->img->left_margin;
$this->img->left_margin += $this->img->plotwidth+1;
$this->scale->AutoScale($this->img,0,$max,
$this->img->plotwidth/$this->xtick_factor/2);
$this->img->plotwidth = $t1;
$this->img->left_margin = $t2;
}
if( $this->iType == POLAR_180 )
$pos = $this->img->height - $this->img->bottom_margin;
else
$pos = $this->img->plotheight/2 + $this->img->top_margin;
if( !$_csim ) {
$this->StrokePlotArea();
}
$this->iDoClipping = true;
if( $this->iDoClipping ) {
$oldimage = $this->img->CloneCanvasH();
}
if( !$_csim ) {
$this->axis->StrokeGrid($pos);
}
// Stroke all plots for Y1 axis
for($i=0; $i < count($this->plots); ++$i) {
$this->plots[$i]->Stroke($this->img,$this->scale);
}
if( $this->iDoClipping ) {
// Clipping only supports graphs at 0 and 90 degrees
if( $this->img->a == 0 ) {
$this->img->CopyCanvasH($oldimage,$this->img->img,
$this->img->left_margin,$this->img->top_margin,
$this->img->left_margin,$this->img->top_margin,
$this->img->plotwidth+1,$this->img->plotheight+1);
}
elseif( $this->img->a == 90 ) {
$adj = round(($this->img->height - $this->img->width)/2);
$this->img->CopyCanvasH($oldimage,$this->img->img,
$this->img->bottom_margin-$adj,$this->img->left_margin+$adj,
$this->img->bottom_margin-$adj,$this->img->left_margin+$adj,
$this->img->plotheight,$this->img->plotwidth);
}
$this->img->Destroy();
$this->img->SetCanvasH($oldimage);
}
if( !$_csim ) {
$this->axis->Stroke($pos);
$this->axis->StrokeAngleLabels($pos,$this->iType);
}
if( !$_csim ) {
$this->StrokePlotBox();
$this->footer->Stroke($this->img);
// The titles and legends never gets rotated so make sure
// that the angle is 0 before stroking them
$aa = $this->img->SetAngle(0);
$this->StrokeTitles();
}
for($i=0; $i < count($this->plots) ; ++$i ) {
$this->plots[$i]->Legend($this);
}
$this->legend->Stroke($this->img);
if( !$_csim ) {
$this->StrokeTexts();
$this->img->SetAngle($aa);
// Draw an outline around the image map
if(_JPG_DEBUG)
$this->DisplayClientSideaImageMapAreas();
// Adjust the appearance of the image
$this->AdjustSaturationBrightnessContrast();
// If the filename is given as the special "__handle"
// then the image handler is returned and the image is NOT
// streamed back
if( $aStrokeFileName == _IMG_HANDLER ) {
return $this->img->img;
}
else {
// Finally stream the generated picture
$this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,
$aStrokeFileName);
}
}
}
}
?>

View File

@ -1,728 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_RADAR.PHP
// Description: Radar plot extension for JpGraph
// Created: 2001-02-04
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_radar.php 606 2006-03-23 18:37:57Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
require_once('jpgraph_plotmark.inc.php');
class RadarLogTicks extends Ticks {
//---------------
// CONSTRUCTOR
function RadarLogTicks() {
}
//---------------
// PUBLIC METHODS
// TODO: Add Argument grid
function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) {
$start = $aScale->GetMinVal();
$limit = $aScale->GetMaxVal();
$nextMajor = 10*$start;
$step = $nextMajor / 10.0;
$count=1;
$ticklen_maj=5;
$dx_maj=round(sin($aAxisAngle)*$ticklen_maj);
$dy_maj=round(cos($aAxisAngle)*$ticklen_maj);
$ticklen_min=3;
$dx_min=round(sin($aAxisAngle)*$ticklen_min);
$dy_min=round(cos($aAxisAngle)*$ticklen_min);
$aMajPos=array();
$aMajLabel=array();
if( $this->supress_first )
$aMajLabel[]="";
else
$aMajLabel[]=$start;
$yr=$aScale->RelTranslate($start);
$xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0];
$yt=$aPos-round($yr*sin($aAxisAngle));
$aMajPos[]=$xt+2*$dx_maj;
$aMajPos[]=$yt-$aImg->GetFontheight()/2;
$grid[]=$xt;
$grid[]=$yt;
$aImg->SetLineWeight($this->weight);
for($y=$start; $y<=$limit; $y+=$step,++$count ) {
$yr=$aScale->RelTranslate($y);
$xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0];
$yt=$aPos-round($yr*sin($aAxisAngle));
if( $count % 10 == 0 ) {
$grid[]=$xt;
$grid[]=$yt;
$aMajPos[]=$xt+2*$dx_maj;
$aMajPos[]=$yt-$aImg->GetFontheight()/2;
if( !$this->supress_tickmarks ) {
if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor);
$aImg->Line($xt+$dx_maj,$yt+$dy_maj,$xt-$dx_maj,$yt-$dy_maj);
if( $this->majcolor!="" ) $aImg->PopColor();
}
if( $this->label_formfunc != "" ) {
$f=$this->label_formfunc;
$l = call_user_func($f,$nextMajor);
}
else
$l = $nextMajor;
$aMajLabel[]=$l;
$nextMajor *= 10;
$step *= 10;
$count=1;
}
else
if( !$this->supress_minor_tickmarks ) {
if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor);
$aImg->Line($xt+$dx_min,$yt+$dy_min,$xt-$dx_min,$yt-$dy_min);
if( $this->mincolor!="" ) $aImg->PopColor();
}
}
}
}
class RadarLinearTicks extends Ticks { // extends LinearTicks {
private $minor_step=1, $major_step=2;
private $xlabel_offset=0,$xtick_offset=0;
private $maj_ticks_pos=array();
//---------------
// CONSTRUCTOR
function RadarLinearTicks() {
// Empty
}
//---------------
// PUBLIC METHODS
// Return major step size in world coordinates
function GetMajor() {
return $this->major_step;
}
// Return minor step size in world coordinates
function GetMinor() {
return $this->minor_step;
}
// Set Minor and Major ticks (in world coordinates)
function Set($aMajStep,$aMinStep=false) {
if( $aMinStep==false )
$aMinStep=$aMajStep;
if( $aMajStep <= 0 || $aMinStep <= 0 ) {
JpGraphError::Raise(" Minor or major step size is 0. Check that you haven't
got an accidental SetTextTicks(0) in your code.<p>
If this is not the case you might have stumbled upon a bug in JpGraph.
Please report this and if possible include the data that caused the
problem.");
}
$this->major_step=$aMajStep;
$this->minor_step=$aMinStep;
$this->is_set = true;
}
function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) {
// Prepare to draw linear ticks
$maj_step_abs = abs($aScale->scale_factor*$this->major_step);
$min_step_abs = abs($aScale->scale_factor*$this->minor_step);
$nbrmaj = floor(($aScale->world_abs_size)/$maj_step_abs);
$nbrmin = floor(($aScale->world_abs_size)/$min_step_abs);
$skip = round($nbrmin/$nbrmaj); // Don't draw minor ontop of major
// Draw major ticks
$ticklen2=$this->major_abs_size;
$dx=round(sin($aAxisAngle)*$ticklen2);
$dy=round(cos($aAxisAngle)*$ticklen2);
$label=$aScale->scale[0]+$this->major_step;
$aImg->SetLineWeight($this->weight);
// NEW
$aMajPos = array();
$aMajLabel = array();
for($i=1; $i<=$nbrmaj; ++$i) {
$xt=round($i*$maj_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0];
$yt=$aPos-round($i*$maj_step_abs*sin($aAxisAngle));
if( $this->label_formfunc != "" ) {
$f=$this->label_formfunc;
$l = call_user_func($f,$label);
}
else
$l = $label;
$aMajLabel[]=$l;
$label += $this->major_step;
$grid[]=$xt;
$grid[]=$yt;
$aMajPos[($i-1)*2]=$xt+2*$dx;
$aMajPos[($i-1)*2+1]=$yt-$aImg->GetFontheight()/2;
if( !$this->supress_tickmarks ) {
if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor);
$aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy);
if( $this->majcolor!="" ) $aImg->PopColor();
}
}
// Draw minor ticks
$ticklen2=$this->minor_abs_size;
$dx=round(sin($aAxisAngle)*$ticklen2);
$dy=round(cos($aAxisAngle)*$ticklen2);
if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor);
for($i=1; $i<=$nbrmin; ++$i) {
if( ($i % $skip) == 0 ) continue;
$xt=round($i*$min_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0];
$yt=$aPos-round($i*$min_step_abs*sin($aAxisAngle));
$aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy);
}
if( $this->mincolor!="" ) $aImg->PopColor();
}
}
}
//===================================================
// CLASS RadarAxis
// Description: Implements axis for the radar graph
//===================================================
class RadarAxis extends AxisPrototype {
private $title_color="navy";
public $title=null;
//---------------
// CONSTRUCTOR
function RadarAxis($img,$aScale,$color=array(0,0,0)) {
parent::Axis($img,$aScale,$color);
$this->len=$img->plotheight;
$this->title = new Text();
$this->title->SetFont(FF_FONT1,FS_BOLD);
$this->color = array(0,0,0);
}
//---------------
// PUBLIC METHODS
function SetTickLabels($aLabelArray,$aLabelColorArray=null) {
$this->ticks_label = $aLabelArray;
$this->ticks_label_colors = $aLabelColorArray;
}
// Stroke the axis
// $pos = Vertical position of axis
// $aAxisAngle = Axis angle
// $grid = Returns an array with positions used to draw the grid
// $lf = Label flag, TRUE if the axis should have labels
function Stroke($pos,$aAxisAngle,&$grid,$title,$lf) {
$this->img->SetColor($this->color);
// Determine end points for the axis
$x=round($this->scale->world_abs_size*cos($aAxisAngle)+$this->scale->scale_abs[0]);
$y=round($pos-$this->scale->world_abs_size*sin($aAxisAngle));
// Draw axis
$this->img->SetColor($this->color);
$this->img->SetLineWeight($this->weight);
if( !$this->hide )
$this->img->Line($this->scale->scale_abs[0],$pos,$x,$y);
$this->scale->ticks->Stroke($this->img,$grid,$pos,$aAxisAngle,$this->scale,$majpos,$majlabel);
$ncolor=0;
if( isset($this->ticks_label_colors) )
$ncolor=count($this->ticks_label_colors);
// Draw labels
if( $lf && !$this->hide ) {
$this->img->SetFont($this->font_family,$this->font_style,$this->font_size);
$this->img->SetTextAlign("left","top");
$this->img->SetColor($this->label_color);
// majpos contains (x,y) coordinates for labels
if( ! $this->hide_labels ) {
$n = floor(count($majpos)/2);
for($i=0; $i < $n; ++$i) {
// Set specific label color if specified
if( $ncolor > 0 )
$this->img->SetColor($this->ticks_label_colors[$i % $ncolor]);
if( $this->ticks_label != null && isset($this->ticks_label[$i]) )
$this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$this->ticks_label[$i]);
else
$this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$majlabel[$i]);
}
}
}
$this->_StrokeAxisTitle($pos,$aAxisAngle,$title);
}
//---------------
// PRIVATE METHODS
function _StrokeAxisTitle($pos,$aAxisAngle,$title) {
$this->title->Set($title);
$marg=6+$this->title->margin;
$xt=round(($this->scale->world_abs_size+$marg)*cos($aAxisAngle)+$this->scale->scale_abs[0]);
$yt=round($pos-($this->scale->world_abs_size+$marg)*sin($aAxisAngle));
// Position the axis title.
// dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
// that intersects with the extension of the corresponding axis. The code looks a little
// bit messy but this is really the only way of having a reasonable position of the
// axis titles.
if( $this->title->iWordwrap > 0 ) {
$title = wordwrap($title,$this->title->iWordwrap,"\n");
}
$h=$this->img->GetTextHeight($title)*1.2;
$w=$this->img->GetTextWidth($title)*1.2;
while( $aAxisAngle > 2*M_PI ) $aAxisAngle -= 2*M_PI;
if( $aAxisAngle>=7*M_PI/4 || $aAxisAngle <= M_PI/4 ) $dx=0;
if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dx=($aAxisAngle-M_PI/4)*2/M_PI;
if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dx=1;
if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dx=(1-($aAxisAngle-M_PI*5/4)*2/M_PI);
if( $aAxisAngle>=7*M_PI/4 ) $dy=(($aAxisAngle-M_PI)-3*M_PI/4)*2/M_PI;
if( $aAxisAngle<=M_PI/4 ) $dy=(1-$aAxisAngle*2/M_PI);
if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dy=1;
if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dy=(1-($aAxisAngle-3*M_PI/4)*2/M_PI);
if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dy=0;
if( !$this->hide ) {
$this->title->Stroke($this->img,$xt-$dx*$w,$yt-$dy*$h,$title);
}
}
} // Class
//===================================================
// CLASS RadarGrid
// Description: Draws grid for the radar graph
//===================================================
class RadarGrid { //extends Grid {
private $type='solid';
private $grid_color='#DDDDDD';
private $show=false, $weight=1;
//------------
// CONSTRUCTOR
function RadarGrid() {
}
// PUBLIC METHODS
function SetColor($aMajColor) {
$this->grid_color = $aMajColor;
}
function SetWeight($aWeight) {
$this->weight=$aWeight;
}
// Specify if grid should be dashed, dotted or solid
function SetLineStyle($aType) {
$this->type = $aType;
}
// Decide if both major and minor grid should be displayed
function Show($aShowMajor=true) {
$this->show=$aShowMajor;
}
//----------------
// PRIVATE METHODS
function Stroke($img,$grid) {
if( !$this->show ) return;
$nbrticks = count($grid[0])/2;
$nbrpnts = count($grid);
$img->SetColor($this->grid_color);
$img->SetLineWeight($this->weight);
for($i=0; $i<$nbrticks; ++$i) {
for($j=0; $j<$nbrpnts; ++$j) {
$pnts[$j*2]=$grid[$j][$i*2];
$pnts[$j*2+1]=$grid[$j][$i*2+1];
}
for($k=0; $k<$nbrpnts; ++$k ){
$l=($k+1)%$nbrpnts;
if( $this->type == "solid" )
$img->Line($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1]);
elseif( $this->type == "dotted" )
$img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],1,6);
elseif( $this->type == "dashed" )
$img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],2,4);
elseif( $this->type == "longdashed" )
$img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],8,6);
}
$pnts=array();
}
}
} // Class
//===================================================
// CLASS RadarPlot
// Description: Plot a radarplot
//===================================================
class RadarPlot {
public $mark=null;
public $legend="";
private $data=array();
private $fill=false, $fill_color=array(200,170,180);
private $color=array(0,0,0);
private $weight=1;
private $linestyle='solid';
//---------------
// CONSTRUCTOR
function RadarPlot($data) {
$this->data = $data;
$this->mark = new PlotMark();
}
//---------------
// PUBLIC METHODS
function Min() {
return Min($this->data);
}
function Max() {
return Max($this->data);
}
function SetLegend($legend) {
$this->legend=$legend;
}
function SetLineStyle($aStyle) {
$this->linestyle=$aStyle;
}
function SetLineWeight($w) {
$this->weight=$w;
}
function SetFillColor($aColor) {
$this->fill_color = $aColor;
$this->fill = true;
}
function SetFill($f=true) {
$this->fill = $f;
}
function SetColor($aColor,$aFillColor=false) {
$this->color = $aColor;
if( $aFillColor ) {
$this->SetFillColor($aFillColor);
$this->fill = true;
}
}
function GetCSIMareas() {
JpGraphError::RaiseL(18001);
//("Client side image maps not supported for RadarPlots.");
}
function Stroke($img, $pos, $scale, $startangle) {
$nbrpnts = count($this->data);
$astep=2*M_PI/$nbrpnts;
$a=$startangle;
// Rotate each point to the correct axis-angle
// TODO: Update for LogScale
for($i=0; $i<$nbrpnts; ++$i) {
//$c=$this->data[$i];
$cs=$scale->RelTranslate($this->data[$i]);
$x=round($cs*cos($a)+$scale->scale_abs[0]);
$y=round($pos-$cs*sin($a));
/*
$c=log10($c);
$x=round(($c-$scale->scale[0])*$scale->scale_factor*cos($a)+$scale->scale_abs[0]);
$y=round($pos-($c-$scale->scale[0])*$scale->scale_factor*sin($a));
*/
$pnts[$i*2]=$x;
$pnts[$i*2+1]=$y;
$a += $astep;
}
if( $this->fill ) {
$img->SetColor($this->fill_color);
$img->FilledPolygon($pnts);
}
$img->SetLineWeight($this->weight);
$img->SetColor($this->color);
$img->SetLineStyle($this->linestyle);
$pnts[]=$pnts[0];
$pnts[]=$pnts[1];
$img->Polygon($pnts);
$img->SetLineStyle('solid'); // Reset line style to default
// Add plotmarks on top
if( $this->mark->show ) {
for($i=0; $i < $nbrpnts; ++$i) {
$this->mark->Stroke($img,$pnts[$i*2],$pnts[$i*2+1]);
}
}
}
//---------------
// PRIVATE METHODS
function GetCount() {
return count($this->data);
}
function Legend($graph) {
if( $this->legend=="" ) return;
if( $this->fill )
$graph->legend->Add($this->legend,$this->fill_color,$this->mark);
else
$graph->legend->Add($this->legend,$this->color,$this->mark);
}
} // Class
//===================================================
// CLASS RadarGraph
// Description: Main container for a radar graph
//===================================================
class RadarGraph extends Graph {
public $grid,$axis=null;
private $posx,$posy;
private $len;
private $axis_title=null;
//---------------
// CONSTRUCTOR
function RadarGraph($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) {
$this->Graph($width,$height,$cachedName,$timeout,$inline);
$this->posx=$width/2;
$this->posy=$height/2;
$this->len=min($width,$height)*0.35;
$this->SetColor(array(255,255,255));
$this->SetTickDensity(TICKD_NORMAL);
$this->SetScale("lin");
$this->SetGridDepth(DEPTH_FRONT);
}
//---------------
// PUBLIC METHODS
function SupressTickMarks($f=true) {
if( ERR_DEPRECATED )
JpGraphError::RaiseL(18002);
//('RadarGraph::SupressTickMarks() is deprecated. Use HideTickMarks() instead.');
$this->axis->scale->ticks->SupressTickMarks($f);
}
function HideTickMarks($aFlag=true) {
$this->axis->scale->ticks->SupressTickMarks($aFlag);
}
function ShowMinorTickmarks($aFlag=true) {
$this->yscale->ticks->SupressMinorTickMarks(!$aFlag);
}
function SetScale($axtype,$ymin=1,$ymax=1,$dummy1=null,$dumy2=null) {
if( $axtype != "lin" && $axtype != "log" ) {
JpGraphError::RaiseL(18003,$axtype);
//("Illegal scale for radarplot ($axtype). Must be \"lin\" or \"log\"");
}
if( $axtype=="lin" ) {
$this->yscale = new LinearScale($ymin,$ymax);
$this->yscale->ticks = new RadarLinearTicks();
$this->yscale->ticks->SupressMinorTickMarks();
}
elseif( $axtype=="log" ) {
$this->yscale = new LogScale($ymin,$ymax);
$this->yscale->ticks = new RadarLogTicks();
}
$this->axis = new RadarAxis($this->img,$this->yscale);
$this->grid = new RadarGrid();
}
function SetSize($aSize) {
if( $aSize < 0.1 || $aSize>1 )
JpGraphError::RaiseL(18004,$aSize);
//("Radar Plot size must be between 0.1 and 1. (Your value=$s)");
$this->len=min($this->img->width,$this->img->height)*$aSize/2;
}
function SetPlotSize($aSize) {
$this->SetSize($aSize);
}
function SetTickDensity($densy=TICKD_NORMAL,$dummy1=null) {
$this->ytick_factor=25;
switch( $densy ) {
case TICKD_DENSE:
$this->ytick_factor=12;
break;
case TICKD_NORMAL:
$this->ytick_factor=25;
break;
case TICKD_SPARSE:
$this->ytick_factor=40;
break;
case TICKD_VERYSPARSE:
$this->ytick_factor=70;
break;
default:
JpGraphError::RaiseL(18005,$densy);
//("RadarPlot Unsupported Tick density: $densy");
}
}
function SetPos($px,$py=0.5) {
$this->SetCenter($px,$py);
}
function SetCenter($px,$py=0.5) {
assert($px > 0 && $py > 0 );
$this->posx=$this->img->width*$px;
$this->posy=$this->img->height*$py;
}
function SetColor($c) {
$this->SetMarginColor($c);
}
function SetTitles($title) {
$this->axis_title = $title;
}
function Add($splot) {
$this->plots[]=$splot;
}
function GetPlotsYMinMax($aPlots) {
$min=$aPlots[0]->Min();
$max=$aPlots[0]->Max();
foreach( $this->plots as $p ) {
$max=max($max,$p->Max());
$min=min($min,$p->Min());
}
if( $min < 0 )
JpGraphError::RaiseL(18006,$min);
//("Minimum data $min (Radar plots should only be used when all data points > 0)");
return array($min,$max);
}
// Stroke the Radar graph
function Stroke($aStrokeFileName="") {
$n = count($this->plots);
// Set Y-scale
if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) {
list($min,$max) = $this->GetPlotsYMinMax($this->plots);
$this->yscale->AutoScale($this->img,0,$max,$this->len/$this->ytick_factor);
}
elseif( $this->yscale->IsSpecified() &&
( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) {
// The tick calculation will use the user suplied min/max values to determine
// the ticks. If auto_ticks is false the exact user specifed min and max
// values will be used for the scale.
// If auto_ticks is true then the scale might be slightly adjusted
// so that the min and max values falls on an even major step.
$min = $this->yscale->scale[0];
$max = $this->yscale->scale[1];
$this->yscale->AutoScale($this->img,$min,$max,
$this->len/$this->ytick_factor,
$this->yscale->auto_ticks);
}
// Set start position end length of scale (in absolute pixels)
$this->yscale->SetConstants($this->posx,$this->len);
// We need as many axis as there are data points
$nbrpnts=$this->plots[0]->GetCount();
// If we have no titles just number the axis 1,2,3,...
if( $this->axis_title==null ) {
for($i=0; $i < $nbrpnts; ++$i )
$this->axis_title[$i] = $i+1;
}
elseif(count($this->axis_title)<$nbrpnts)
JpGraphError::RaiseL(18007);
//("Number of titles does not match number of points in plot.");
for($i=0; $i < $n; ++$i )
if( $nbrpnts != $this->plots[$i]->GetCount() )
JpGraphError::RaiseL(18008);
//("Each radar plot must have the same number of data points.");
if( $this->background_image != "" ) {
$this->StrokeFrameBackground();
}
else {
$this->StrokeFrame();
}
$astep=2*M_PI/$nbrpnts;
// Prepare legends
for($i=0; $i < $n; ++$i)
$this->plots[$i]->Legend($this);
$this->legend->Stroke($this->img);
$this->footer->Stroke($this->img);
if( $this->grid_depth == DEPTH_BACK ) {
// Draw axis and grid
for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) {
$this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0);
}
}
// Plot points
$a=M_PI/2;
for($i=0; $i < $n; ++$i )
$this->plots[$i]->Stroke($this->img, $this->posy, $this->yscale, $a);
if( $this->grid_depth != DEPTH_BACK ) {
// Draw axis and grid
for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) {
$this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0);
}
}
$this->grid->Stroke($this->img,$grid);
$this->StrokeTitles();
// Stroke texts
if( $this->texts != null ) {
foreach( $this->texts as $t)
$t->Stroke($this->img);
}
// Should we do any final image transformation
if( $this->iImgTrans ) {
if( !class_exists('ImgTrans',false) ) {
require_once('jpgraph_imgtrans.php');
}
$tform = new ImgTrans($this->img->img);
$this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist,
$this->iImgTransDirection,$this->iImgTransHighQ,
$this->iImgTransMinSize,$this->iImgTransFillColor,
$this->iImgTransBorder);
}
// If the filename is given as the special "__handle"
// then the image handler is returned and the image is NOT
// streamed back
if( $aStrokeFileName == _IMG_HANDLER ) {
return $this->img->img;
}
else {
// Finally stream the generated picture
$this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,
$aStrokeFileName);
}
}
} // Class
/* EOF */
?>

View File

@ -1,203 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_REGSTAT.PHP
// Description: Regression and statistical analysis helper classes
// Created: 2002-12-01
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_regstat.php 614 2006-04-19 19:36:32Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//------------------------------------------------------------------------
// CLASS Spline
// Create a new data array from an existing data array but with more points.
// The new points are interpolated using a cubic spline algorithm
//------------------------------------------------------------------------
class Spline {
// 3:rd degree polynom approximation
private $xdata,$ydata; // Data vectors
private $y2; // 2:nd derivate of ydata
private $n=0;
function Spline($xdata,$ydata) {
$this->y2 = array();
$this->xdata = $xdata;
$this->ydata = $ydata;
$n = count($ydata);
$this->n = $n;
if( $this->n !== count($xdata) ) {
JpGraphError::RaiseL(19001);
//('Spline: Number of X and Y coordinates must be the same');
}
// Natural spline 2:derivate == 0 at endpoints
$this->y2[0] = 0.0;
$this->y2[$n-1] = 0.0;
$delta[0] = 0.0;
// Calculate 2:nd derivate
for($i=1; $i < $n-1; ++$i) {
$d = ($xdata[$i+1]-$xdata[$i-1]);
if( $d == 0 ) {
JpGraphError::RaiseL(19002);
//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
}
$s = ($xdata[$i]-$xdata[$i-1])/$d;
$p = $s*$this->y2[$i-1]+2.0;
$this->y2[$i] = ($s-1.0)/$p;
$delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) -
($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]);
$delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p;
}
// Backward substitution
for( $j=$n-2; $j >= 0; --$j ) {
$this->y2[$j] = $this->y2[$j]*$this->y2[$j+1] + $delta[$j];
}
}
// Return the two new data vectors
function Get($num=50) {
$n = $this->n ;
$step = ($this->xdata[$n-1]-$this->xdata[0]) / ($num-1);
$xnew=array();
$ynew=array();
$xnew[0] = $this->xdata[0];
$ynew[0] = $this->ydata[0];
for( $j=1; $j < $num; ++$j ) {
$xnew[$j] = $xnew[0]+$j*$step;
$ynew[$j] = $this->Interpolate($xnew[$j]);
}
return array($xnew,$ynew);
}
// Return a single interpolated Y-value from an x value
function Interpolate($xpoint) {
$max = $this->n-1;
$min = 0;
// Binary search to find interval
while( $max-$min > 1 ) {
$k = ($max+$min) / 2;
if( $this->xdata[$k] > $xpoint )
$max=$k;
else
$min=$k;
}
// Each interval is interpolated by a 3:degree polynom function
$h = $this->xdata[$max]-$this->xdata[$min];
if( $h == 0 ) {
JpGraphError::RaiseL(19002);
//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
}
$a = ($this->xdata[$max]-$xpoint)/$h;
$b = ($xpoint-$this->xdata[$min])/$h;
return $a*$this->ydata[$min]+$b*$this->ydata[$max]+
(($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0;
}
}
//------------------------------------------------------------------------
// CLASS Bezier
// Create a new data array from a number of control points
//------------------------------------------------------------------------
class Bezier {
/**
* @author Thomas Despoix, openXtrem company
* @license released under QPL
* @abstract Bezier interoplated point generation,
* computed from control points data sets, based on Paul Bourke algorithm :
* http://astronomy.swin.edu.au/~pbourke/curves/bezier/
*/
private $datax = array();
private $datay = array();
private $n=0;
function Bezier($datax, $datay, $attraction_factor = 1) {
// Adding control point multiple time will raise their attraction power over the curve
$this->n = count($datax);
if( $this->n !== count($datay) ) {
JpGraphError::RaiseL(19003);
//('Bezier: Number of X and Y coordinates must be the same');
}
$idx=0;
foreach($datax as $datumx) {
for ($i = 0; $i < $attraction_factor; $i++) {
$this->datax[$idx++] = $datumx;
}
}
$idx=0;
foreach($datay as $datumy) {
for ($i = 0; $i < $attraction_factor; $i++) {
$this->datay[$idx++] = $datumy;
}
}
$this->n *= $attraction_factor;
}
function Get($steps) {
$datax = array();
$datay = array();
for ($i = 0; $i < $steps; $i++) {
list($datumx, $datumy) = $this->GetPoint((double) $i / (double) $steps);
$datax[] = $datumx;
$datay[] = $datumy;
}
$datax[] = end($this->datax);
$datay[] = end($this->datay);
return array($datax, $datay);
}
function GetPoint($mu) {
$n = $this->n - 1;
$k = 0;
$kn = 0;
$nn = 0;
$nkn = 0;
$blend = 0.0;
$newx = 0.0;
$newy = 0.0;
$muk = 1.0;
$munk = (double) pow(1-$mu,(double) $n);
for ($k = 0; $k <= $n; $k++) {
$nn = $n;
$kn = $k;
$nkn = $n - $k;
$blend = $muk * $munk;
$muk *= $mu;
$munk /= (1-$mu);
while ($nn >= 1) {
$blend *= $nn;
$nn--;
if ($kn > 1) {
$blend /= (double) $kn;
$kn--;
}
if ($nkn > 1) {
$blend /= (double) $nkn;
$nkn--;
}
}
$newx += $this->datax[$k] * $blend;
$newy += $this->datay[$k] * $blend;
}
return array($newx, $newy);
}
}
// EOF
?>

View File

@ -1,225 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_SCATTER.PHP
// Description: Scatter (and impuls) plot extension for JpGraph
// Created: 2001-02-11
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_scatter.php 492 2006-02-04 12:29:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
require_once ('jpgraph_plotmark.inc.php');
//===================================================
// CLASS FieldArrow
// Description: Draw an arrow at (x,y) with angle a
//===================================================
class FieldArrow {
public $iColor='black';
public $iSize=10; // Length in pixels for arrow
public $iArrowSize = 2;
private $isizespec = array(
array(2,1),array(3,2),array(4,3),array(6,4),array(7,4),array(8,5),array(10,6),array(12,7),array(16,8),array(20,10));
function FieldArrow() {
}
function SetSize($aSize,$aArrowSize=2) {
$this->iSize = $aSize;
$this->iArrowSize = $aArrowSize;
}
function SetColor($aColor) {
$this->iColor = $aColor;
}
function Stroke($aImg,$x,$y,$a) {
// First rotate the center coordinates
list($x,$y) = $aImg->Rotate($x,$y);
$old_origin = $aImg->SetCenter($x,$y);
$old_a = $aImg->a;
$aImg->SetAngle(-$a+$old_a);
$dx = round($this->iSize/2);
$c = array($x-$dx,$y,$x+$dx,$y);
$x += $dx;
list($dx,$dy) = $this->isizespec[$this->iArrowSize];
$ca = array($x,$y,$x-$dx,$y-$dy,$x-$dx,$y+$dy,$x,$y);
$aImg->SetColor($this->iColor);
$aImg->Polygon($c);
$aImg->FilledPolygon($ca);
$aImg->SetCenter($old_origin[0],$old_origin[1]);
$aImg->SetAngle($old_a);
}
}
//===================================================
// CLASS FieldPlot
// Description: Render a field plot
//===================================================
class FieldPlot extends Plot {
private $iAngles;
private $iCallback='';
function FieldPlot($datay,$datax,$angles) {
if( (count($datax) != count($datay)) )
JpGraphError::RaiseL(20001);//("Fieldplots must have equal number of X and Y points.");
if( (count($datax) != count($angles)) )
JpGraphError::RaiseL(20002);//("Fieldplots must have an angle specified for each X and Y points.");
$this->iAngles = $angles;
$this->Plot($datay,$datax);
$this->value->SetAlign('center','center');
$this->value->SetMargin(15);
$this->arrow = new FieldArrow();
}
function SetCallback($aFunc) {
$this->iCallback = $aFunc;
}
function Stroke($img,$xscale,$yscale) {
// Remeber base color and size
$bc = $this->arrow->iColor;
$bs = $this->arrow->iSize;
$bas = $this->arrow->iArrowSize;
for( $i=0; $i<$this->numpoints; ++$i ) {
// Skip null values
if( $this->coords[0][$i]==="" )
continue;
$f = $this->iCallback;
if( $f != "" ) {
list($cc,$cs,$cas) = call_user_func($f,$this->coords[1][$i],$this->coords[0][$i],$this->iAngles[$i]);
// Fall back on global data if the callback isn't set
if( $cc == "" ) $cc = $bc;
if( $cs == "" ) $cs = $bs;
if( $cas == "" ) $cas = $bas;
//echo "f=$f, cc=$cc, cs=$cs, cas=$cas<br>";
$this->arrow->SetColor($cc);
$this->arrow->SetSize($cs,$cas);
}
$xt = $xscale->Translate($this->coords[1][$i]);
$yt = $yscale->Translate($this->coords[0][$i]);
$this->arrow->Stroke($img,$xt,$yt,$this->iAngles[$i]);
$this->value->Stroke($img,$this->coords[0][$i],$xt,$yt);
}
}
// Framework function
function Legend($aGraph) {
if( $this->legend != "" ) {
$aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0,
$this->legendcsimtarget,$this->legendcsimalt);
}
}
}
//===================================================
// CLASS ScatterPlot
// Description: Render X and Y plots
//===================================================
class ScatterPlot extends Plot {
private $impuls = false;
private $linkpoints = false, $linkpointweight=1, $linkpointcolor="black";
//---------------
// CONSTRUCTOR
function ScatterPlot($datay,$datax=false) {
if( (count($datax) != count($datay)) && is_array($datax))
JpGraphError::RaiseL(20003);//("Scatterplot must have equal number of X and Y points.");
$this->Plot($datay,$datax);
$this->mark = new PlotMark();
$this->mark->SetType(MARK_SQUARE);
$this->mark->SetColor($this->color);
$this->value->SetAlign('center','center');
$this->value->SetMargin(0);
}
//---------------
// PUBLIC METHODS
function SetImpuls($f=true) {
$this->impuls = $f;
}
// Combine the scatter plot points with a line
function SetLinkPoints($aFlag=true,$aColor="black",$aWeight=1) {
$this->linkpoints=$aFlag;
$this->linkpointcolor=$aColor;
$this->linkpointweight=$aWeight;
}
function Stroke($img,$xscale,$yscale) {
$ymin=$yscale->scale_abs[0];
if( $yscale->scale[0] < 0 )
$yzero=$yscale->Translate(0);
else
$yzero=$yscale->scale_abs[0];
$this->csimareas = '';
for( $i=0; $i<$this->numpoints; ++$i ) {
// Skip null values
if( $this->coords[0][$i]==='' || $this->coords[0][$i]==='-' || $this->coords[0][$i]==='x')
continue;
if( isset($this->coords[1]) )
$xt = $xscale->Translate($this->coords[1][$i]);
else
$xt = $xscale->Translate($i);
$yt = $yscale->Translate($this->coords[0][$i]);
if( $this->linkpoints && isset($yt_old) ) {
$img->SetColor($this->linkpointcolor);
$img->SetLineWeight($this->linkpointweight);
$img->Line($xt_old,$yt_old,$xt,$yt);
}
if( $this->impuls ) {
$img->SetColor($this->color);
$img->SetLineWeight($this->weight);
$img->Line($xt,$yzero,$xt,$yt);
}
if( !empty($this->csimtargets[$i]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$i]);
$this->mark->SetCSIMAlt($this->csimalts[$i]);
}
if( isset($this->coords[1]) ) {
$this->mark->SetCSIMAltVal($this->coords[0][$i],$this->coords[1][$i]);
}
else {
$this->mark->SetCSIMAltVal($this->coords[0][$i],$i);
}
$this->mark->Stroke($img,$xt,$yt);
$this->csimareas .= $this->mark->GetCSIMAreas();
$this->value->Stroke($img,$this->coords[0][$i],$xt,$yt);
$xt_old = $xt;
$yt_old = $yt;
}
}
// Framework function
function Legend($aGraph) {
if( $this->legend != "" ) {
$aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0,
$this->legendcsimtarget,$this->legendcsimalt);
}
}
} // Class
/* EOF */
?>

View File

@ -1,184 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_STOCK.PHP
// Description: Stock plot extension for JpGraph
// Created: 2003-01-27
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: jpgraph_stock.php 494 2006-02-04 12:31:05Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//===================================================
// CLASS StockPlot
//===================================================
class StockPlot extends Plot {
protected $iTupleSize = 4;
private $iWidth=9;
private $iEndLines=1;
private $iStockColor1='white',$iStockColor2='darkred',$iStockColor3='darkred';
//---------------
// CONSTRUCTOR
function StockPlot($datay,$datax=false) {
if( count($datay) % $this->iTupleSize ) {
JpGraphError::RaiseL(21001,$this->iTupleSize);
//('Data values for Stock charts must contain an even multiple of '.$this->iTupleSize.' data points.');
}
$this->Plot($datay,$datax);
$this->numpoints /= $this->iTupleSize;
}
//---------------
// PUBLIC METHODS
function SetColor($aColor,$aColor1='white',$aColor2='darkred',$aColor3='darkred') {
$this->color = $aColor;
$this->iStockColor1 = $aColor1;
$this->iStockColor2 = $aColor2;
$this->iStockColor3 = $aColor3;
}
function SetWidth($aWidth) {
// Make sure it's odd
$this->iWidth = 2*floor($aWidth/2)+1;
}
function HideEndLines($aHide=true) {
$this->iEndLines = !$aHide;
}
// Gets called before any axis are stroked
function PreStrokeAdjust($graph) {
if( $this->center ) {
$a=0.5; $b=0.5;
$this->numpoints++;
} else {
$a=0; $b=0;
}
$graph->xaxis->scale->ticks->SetXLabelOffset($a);
$graph->SetTextScaleOff($b);
}
// Method description
function Stroke($img,$xscale,$yscale) {
$n=$this->numpoints;
if( $this->center ) $n--;
if( isset($this->coords[1]) ) {
if( count($this->coords[1])!=$n )
JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
//("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
else
$exist_x = true;
}
else
$exist_x = false;
if( $exist_x )
$xs=$this->coords[1][0];
else
$xs=0;
$ts = $this->iTupleSize;
$this->csimareas = '';
for( $i=0; $i<$n; ++$i) {
//If value is NULL, then don't draw a bar at all
if ($this->coords[0][$i] === null) continue;
if( $exist_x ) $x=$this->coords[1][$i];
else $x=$i;
$xt = $xscale->Translate($x);
$neg = $this->coords[0][$i*$ts] > $this->coords[0][$i*$ts+1] ;
$yopen = $yscale->Translate($this->coords[0][$i*$ts]);
$yclose = $yscale->Translate($this->coords[0][$i*$ts+1]);
$ymin = $yscale->Translate($this->coords[0][$i*$ts+2]);
$ymax = $yscale->Translate($this->coords[0][$i*$ts+3]);
$dx = floor($this->iWidth/2);
$xl = $xt - $dx;
$xr = $xt + $dx;
if( $neg )
$img->SetColor($this->iStockColor3);
else
$img->SetColor($this->iStockColor1);
$img->FilledRectangle($xl,$yopen,$xr,$yclose);
$img->SetLineWeight($this->weight);
if( $neg )
$img->SetColor($this->iStockColor2);
else
$img->SetColor($this->color);
$img->Rectangle($xl,$yopen,$xr,$yclose);
if( $yopen < $yclose ) {
$ytop = $yopen ;
$ybottom = $yclose ;
}
else {
$ytop = $yclose ;
$ybottom = $yopen ;
}
$img->SetColor($this->color);
$img->Line($xt,$ytop,$xt,$ymax);
$img->Line($xt,$ybottom,$xt,$ymin);
if( $this->iEndLines ) {
$img->Line($xl,$ymax,$xr,$ymax);
$img->Line($xl,$ymin,$xr,$ymin);
}
// A chance for subclasses to add things to the bar
// for data point i
$this->ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg);
// Setup image maps
if( !empty($this->csimtargets[$i]) ) {
$this->csimareas.= '<area shape="rect" coords="'.
round($xl).','.round($ytop).','.
round($xr).','.round($ybottom).'" ';
$this->csimareas .= ' href="'.$this->csimtargets[$i].'"';
if( !empty($this->csimalts[$i]) ) {
$sval=$this->csimalts[$i];
$this->csimareas .= " title=\"$sval\" ";
}
$this->csimareas.= " alt=\"$sval\" />\n";
}
}
return true;
}
// A hook for subclasses to modify the plot
function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) {}
} // Class
//===================================================
// CLASS BoxPlot
//===================================================
class BoxPlot extends StockPlot {
private $iPColor='black',$iNColor='white';
function BoxPlot($datay,$datax=false) {
$this->iTupleSize=5;
parent::StockPlot($datay,$datax);
}
function SetMedianColor($aPos,$aNeg) {
$this->iPColor = $aPos;
$this->iNColor = $aNeg;
}
function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) {
if( $neg )
$img->SetColor($this->iNColor);
else
$img->SetColor($this->iPColor);
$y = $yscale->Translate($this->coords[0][$i*5+4]);
$img->Line($xl,$y,$xr,$y);
}
}
/* EOF */
?>

View File

@ -1,568 +0,0 @@
<?php
/*=======================================================================
// File: JPGRAPH_UTILS.INC
// Description: Collection of non-essential "nice to have" utilities
// Created: 2005-11-20
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id$
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
//===================================================
// CLASS FuncGenerator
// Description: Utility class to help generate data for function plots.
// The class supports both parametric and regular functions.
//===================================================
class FuncGenerator {
var $iFunc='',$iXFunc='',$iMin,$iMax,$iStepSize;
function FuncGenerator($aFunc,$aXFunc='') {
$this->iFunc = $aFunc;
$this->iXFunc = $aXFunc;
}
function E($aXMin,$aXMax,$aSteps=50) {
$this->iMin = $aXMin;
$this->iMax = $aXMax;
$this->iStepSize = ($aXMax-$aXMin)/$aSteps;
if( $this->iXFunc != '' )
$t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}';
elseif( $this->iFunc != '' )
$t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;';
else
JpGraphError::Raise('FuncGenerator : No function specified. ');
@eval($t);
// If there is an error in the function specifcation this is the only
// way we can discover that.
if( empty($xa) || empty($ya) )
JpGraphError::Raise('FuncGenerator : Syntax error in function specification ');
return array($xa,$ya);
}
}
//=============================================================================
// CLASS SymChar
// Description: Code values for some commonly used characters that
// normally isn't available directly on the keyboard, for example
// mathematical and greek symbols.
//=============================================================================
class SymChar {
function Get($aSymb,$aCapital=FALSE) {
static $iSymbols = array(
/* Greek */
array('alpha','03B1','0391'),
array('beta','03B2','0392'),
array('gamma','03B3','0393'),
array('delta','03B4','0394'),
array('epsilon','03B5','0395'),
array('zeta','03B6','0396'),
array('ny','03B7','0397'),
array('eta','03B8','0398'),
array('theta','03B8','0398'),
array('iota','03B9','0399'),
array('kappa','03BA','039A'),
array('lambda','03BB','039B'),
array('mu','03BC','039C'),
array('nu','03BD','039D'),
array('xi','03BE','039E'),
array('omicron','03BF','039F'),
array('pi','03C0','03A0'),
array('rho','03C1','03A1'),
array('sigma','03C3','03A3'),
array('tau','03C4','03A4'),
array('upsilon','03C5','03A5'),
array('phi','03C6','03A6'),
array('chi','03C7','03A7'),
array('psi','03C8','03A8'),
array('omega','03C9','03A9'),
/* Money */
array('euro','20AC'),
array('yen','00A5'),
array('pound','20A4'),
/* Math */
array('approx','2248'),
array('neq','2260'),
array('not','2310'),
array('def','2261'),
array('inf','221E'),
array('sqrt','221A'),
array('int','222B'),
/* Misc */
array('copy','00A9'),
array('para','00A7'));
$n = count($iSymbols);
$i=0;
$found = false;
$aSymb = strtolower($aSymb);
while( $i < $n && !$found ) {
$found = $aSymb === $iSymbols[$i++][0];
}
if( $found ) {
$ca = $iSymbols[--$i];
if( $aCapital && count($ca)==3 )
$s = $ca[2];
else
$s = $ca[1];
return sprintf('&#%04d;',hexdec($s));
}
else
return '';
}
}
//=============================================================================
// CLASS MGraph
// Description: Create a container image that can hold several graph
//=============================================================================
class MGraph {
var $img=NULL;
var $iCnt=0,$iGraphs = array(); // image_handle, x, y, fx, fy, sizex, sizey
var $iFillColor='white', $iCurrentColor=0;
var $lm=0,$rm=0,$tm=0,$bm=0;
var $iDoFrame = FALSE, $iFrameColor = 'black', $iFrameWeight = 1;
var $iLineWeight = 1;
var $expired=false;
var $img_format='png',$image_quality=75;
var $iWidth=NULL,$iHeight=NULL;
var $background_image='',$background_image_center=true,
$backround_image_format='',$background_image_mix=100,
$background_image_y=NULL, $background_image_x=NULL;
// Create a new instane of the combined graph
function MGraph($aWidth=NULL,$aHeight=NULL) {
$this->iWidth = $aWidth;
$this->iHeight = $aHeight;
}
// Specify background fill color for the combined graph
function SetFillColor($aColor) {
$this->iFillColor = $aColor;
}
// Add a frame around the combined graph
function SetFrame($aFlg,$aColor='black',$aWeight=1) {
$this->iDoFrame = $aFlg;
$this->iFrameColor = $aColor;
$this->iFrameWeight = $aWeight;
}
// Specify a background image blend
function SetBackgroundImageMix($aMix) {
$this->background_image_mix = $aMix ;
}
// Specify a background image
function SetBackgroundImage($aFileName,$aCenter_aX=NULL,$aY=NULL) {
// Second argument can be either a boolean value or
// a numeric
$aCenter=TRUE;
$aX=NULL;
if( $GLOBALS['gd2'] && !USE_TRUECOLOR ) {
JpGraphError::Raise("You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x you <b>must</b> enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts.");
}
if( is_numeric($aCenter_aX) ) {
$aX=$aCenter_aX;
}
// Get extension to determine image type
$e = explode('.',$aFileName);
if( !$e ) {
JpGraphError::Raise('Incorrect file name for MGraph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type');
}
$valid_formats = array('png', 'jpg', 'gif');
$aImgFormat = strtolower($e[count($e)-1]);
if ($aImgFormat == 'jpeg') {
$aImgFormat = 'jpg';
}
elseif (!in_array($aImgFormat, $valid_formats) ) {
JpGraphError::Raise('Unknown file extension ($aImgFormat) in MGraph::SetBackgroundImage() for filename: '.$aFileName);
}
$this->background_image = $aFileName;
$this->background_image_center=$aCenter;
$this->background_image_format=$aImgFormat;
$this->background_image_x = $aX;
$this->background_image_y = $aY;
}
// Private helper function for backgound image
function _loadBkgImage($aFile='') {
if( $aFile == '' )
$aFile = $this->background_image;
// Remove case sensitivity and setup appropriate function to create image
// Get file extension. This should be the LAST '.' separated part of the filename
$e = explode('.',$aFile);
$ext = strtolower($e[count($e)-1]);
if ($ext == "jpeg") {
$ext = "jpg";
}
if( trim($ext) == '' )
$ext = 'png'; // Assume PNG if no extension specified
$supported = imagetypes();
if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) ||
( $ext == 'gif' && !($supported & IMG_GIF) ) ||
( $ext == 'png' && !($supported & IMG_PNG) ) ) {
JpGraphError::Raise('The image format of your background image ('.$aFile.') is not supported in your system configuration. ');
}
if( $ext == "jpg" || $ext == "jpeg") {
$f = "imagecreatefromjpeg";
$ext = "jpg";
}
else {
$f = "imagecreatefrom".$ext;
}
$img = @$f($aFile);
if( !$img ) {
JpGraphError::Raise(" Can't read background image: '".$aFile."'");
}
return $img;
}
function _strokeBackgroundImage() {
if( $this->background_image == '' )
return;
$bkgimg = $this->_loadBkgImage();
// Background width & Heoght
$bw = imagesx($bkgimg);
$bh = imagesy($bkgimg);
// Canvas width and height
$cw = imagesx($this->img);
$ch = imagesy($this->img);
if( $this->background_image_x === NULL || $this->background_image_y === NULL ) {
if( $this->background_image_center ) {
// Center original image in the plot area
$x = round($cw/2-$bw/2); $y = round($ch/2-$bh/2);
}
else {
// Just copy the image from left corner, no resizing
$x=0; $y=0;
}
}
else {
$x = $this->background_image_x;
$y = $this->background_image_y;
}
$this->_imageCp($bkgimg,$x,$y,0,0,$bw,$bh,$this->background_image_mix);
}
function _imageCp($aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix=100) {
imagecopymerge($this->img,$aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix);
}
function _imageCreate($aWidth,$aHeight) {
if( $aWidth <= 1 || $aHeight <= 1 ) {
JpGraphError::Raise("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)");
}
if( @$GLOBALS['gd2']==true && USE_TRUECOLOR ) {
$this->img = @imagecreatetruecolor($aWidth, $aHeight);
if( $this->img < 1 ) {
die("<b>JpGraph Error:</b> Can't create truecolor image. Check that you really have GD2 library installed.");
}
ImageAlphaBlending($this->img,true);
} else {
$this->img = @imagecreate($aWidth, $aHeight);
if( $this->img < 1 ) {
die("<b>JpGraph Error:</b> Can't create image. Check that you really have the GD library installed.");
}
}
}
function _polygon($p,$closed=FALSE) {
if( $this->iLineWeight==0 ) return;
$n=count($p);
$oldx = $p[0];
$oldy = $p[1];
for( $i=2; $i < $n; $i+=2 ) {
imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->iCurrentColor);
$oldx = $p[$i];
$oldy = $p[$i+1];
}
if( $closed ) {
imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->iCurrentColor);
}
}
function _filledPolygon($pts) {
$n=count($pts);
for($i=0; $i < $n; ++$i)
$pts[$i] = round($pts[$i]);
imagefilledpolygon($this->img,$pts,count($pts)/2,$this->iCurrentColor);
}
function _rectangle($xl,$yu,$xr,$yl) {
for($i=0; $i < $this->iLineWeight; ++$i )
$this->_polygon(array($xl+$i,$yu+$i,$xr-$i,$yu+$i,
$xr-$i,$yl-$i,$xl+$i,$yl-$i,
$xl+$i,$yu+$i));
}
function _filledRectangle($xl,$yu,$xr,$yl) {
$this->_filledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl));
}
function _setColor($aColor) {
$this->iCurrentColor = $this->iRGB->Allocate($aColor);
}
function AddMix($aGraph,$x=0,$y=0,$mix=100,$fx=0,$fy=0,$w=0,$h=0) {
$this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h,$mix);
}
function Add($aGraph,$x=0,$y=0,$fx=0,$fy=0,$w=0,$h=0) {
$this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h);
}
function _gdImgHandle($agdCanvas,$x,$y,$fx=0,$fy=0,$w=0,$h=0,$mix=100) {
if( $w == 0 ) $w = @imagesx($agdCanvas);
if( $w === NULL ) {
JpGraphError::Raise('Argument to MGraph::Add() is not a valid GD image handle.');
return;
}
if( $h == 0 ) $h = @imagesy($agdCanvas);
$this->iGraphs[$this->iCnt++] = array($agdCanvas,$x,$y,$fx,$fy,$w,$h,$mix);
}
function SetMargin($lm,$rm,$tm,$bm) {
$this->lm = $lm;
$this->rm = $rm;
$this->tm = $tm;
$this->bm = $bm;
}
function SetExpired($aFlg=true) {
$this->expired = $aFlg;
}
// Generate image header
function Headers() {
// In case we are running from the command line with the client version of
// PHP we can't send any headers.
$sapi = php_sapi_name();
if( $sapi == 'cli' )
return;
if( headers_sent() ) {
echo "<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b>
HTTP headers have already been sent.</font></td></tr><tr><td><b>Explanation:</b><br>HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it's image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).<p>Most likely you have some text in your script before the call to <i>Graph::Stroke()</i>. If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser. <p>For example it is a common mistake to leave a blank line before the opening \"<b>&lt;?php</b>\".</td></tr></table>";
die();
}
if ($this->expired) {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
}
header("Content-type: image/$this->img_format");
}
function SetImgFormat($aFormat,$aQuality=75) {
$this->image_quality = $aQuality;
$aFormat = strtolower($aFormat);
$tst = true;
$supported = imagetypes();
if( $aFormat=="auto" ) {
if( $supported & IMG_PNG )
$this->img_format="png";
elseif( $supported & IMG_JPG )
$this->img_format="jpeg";
elseif( $supported & IMG_GIF )
$this->img_format="gif";
else
JpGraphError::Raise(" Your PHP (and GD-lib) installation does not appear to support any known graphic formats.".
"You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images".
"you must get the JPEG library. Please see the PHP docs for details.");
return true;
}
else {
if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) {
if( $aFormat=="jpeg" && !($supported & IMG_JPG) )
$tst=false;
elseif( $aFormat=="png" && !($supported & IMG_PNG) )
$tst=false;
elseif( $aFormat=="gif" && !($supported & IMG_GIF) )
$tst=false;
else {
$this->img_format=$aFormat;
return true;
}
}
else
$tst=false;
if( !$tst )
JpGraphError::Raise(" Your PHP installation does not support the chosen graphic format: $aFormat");
}
}
// Stream image to browser or to file
function Stream($aFile="") {
$func="image".$this->img_format;
if( $this->img_format=="jpeg" && $this->image_quality != null ) {
$res = @$func($this->img,$aFile,$this->image_quality);
}
else {
if( $aFile != "" ) {
$res = @$func($this->img,$aFile);
}
else
$res = @$func($this->img);
}
if( !$res )
JpGraphError::Raise("Can't create or stream image to file $aFile Check that PHP has enough permission to write a file to the current directory.");
}
function Stroke($aFileName='') {
// Find out the necessary size for the container image
$w=0; $h=0;
for($i=0; $i < $this->iCnt; ++$i ) {
$maxw = $this->iGraphs[$i][1]+$this->iGraphs[$i][5];
$maxh = $this->iGraphs[$i][2]+$this->iGraphs[$i][6];
$w = max( $w, $maxw );
$h = max( $h, $maxh );
}
$w += $this->lm+$this->rm;
$h += $this->tm+$this->bm;
// User specified width,height overrides
if( $this->iWidth !== NULL ) $w = $this->iWidth;
if( $this->iHeight!== NULL ) $h = $this->iHeight;
$this->_imageCreate($w,$h);
$this->iRGB = new RGB($this->img);
$this->_setcolor($this->iFillColor);
$this->_filledRectangle(0,0,$w-1,$h-1);
$this->_strokeBackgroundImage();
if( $this->iDoFrame ) {
$this->_setColor($this->iFrameColor);
$this->iLineWeight=$this->iFrameWeight;
$this->_rectangle(0,0,$w-1,$h-1);
}
// Copy all sub graphs to the container
for($i=0; $i < $this->iCnt; ++$i ) {
$this->_imageCp($this->iGraphs[$i][0],
$this->iGraphs[$i][1]+$this->lm,$this->iGraphs[$i][2]+$this->tm,
$this->iGraphs[$i][3],$this->iGraphs[$i][4],
$this->iGraphs[$i][5],$this->iGraphs[$i][6],
$this->iGraphs[$i][7]);
}
// Output image
if( $aFileName == _IMG_HANDLER ) {
return $this->img;
}
else {
$this->Headers();
$this->Stream($aFileName);
}
}
}
//=============================================================================
// CLASS DateScaleUtils
// Description: Help to create a manual date scale
//=============================================================================
DEFINE('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis
class DateScaleUtils {
function GetTicks($aData,$aType=1) {
//
// Find out the range of the data in order to get the limits for the loops
// that creates the position for the labels. This code is generic and can be
// used for any ranges of the data.
//
$n = count($aData);
$startmonth = date('n',$aData[0]);
$startday = date('j',$aData[0]);
$startyear = date('Y',$aData[0]);
$endmonth = date('n',$aData[$n-1]);
$endyear = date('Y',$aData[$n-1]);
$endday = date('j',$aData[$n-1]);
//
// Now create the positions for all the ticks. In this example we
// put a tick at the start of every month and also on the very
// first and last X-position.
//
$tickPositions = array();
$minTickPositions = array();
$i=0;$j=0;
// Uncomment this line to put a label at the very left data pos
// $tickPositions[$i++] = $datax[0];
$m = $startmonth;
$y = $startyear;
// Skip the first month label if it is before the startdate
if( $startday == 1 ) {
$tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
}
if( $startday < 15 ) {
$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
}
++$m;
// Loop through all the years included in the scale
for($y=$startyear; $y <= $endyear; ++$y ) {
// Loop through all the months. There are three cases to consider:
// 1. We are in the first year and must start with the startmonth
// 2. We are in the end year and we must stop at last month of the scale
// 3. A year in between where we run through all the 12 months
$stopmonth = $y == $endyear ? $endmonth : 12;
while( $m <= $stopmonth ) {
switch( $aType ) {
case 1:
// Set minor tick at the middle of the month
if( $m <= $stopmonth ) {
if( !($y==$endyear && $m==$stopmonth && $endday < 15) )
$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
}
// Major at month
// Get timestamp of first hour of first day in each month
$tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
break;
}
++$m;
}
$m=1;
}
// Uncomment this line to put a label at the very right data pos
// $tickPositions[$i] = $datax[$n-1];
return array($tickPositions,$minTickPositions);
}
}
?>