Subversion Repositories Sites.obs-saisons.fr

Compare Revisions

Problem with comparison.

Ignore whitespace Rev HEAD → Rev 1

/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_gantt.php
New file
0,0 → 1,3808
<?php
/*=======================================================================
// File: JPGRAPH_GANTT.PHP
// Description: JpGraph Gantt plot extension
// Created: 2001-11-12
// Ver: $Id: jpgraph_gantt.php 955 2007-11-17 11:41:42Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
require_once('jpgraph_plotband.php');
require_once('jpgraph_iconplot.php');
require_once('jpgraph_plotmark.inc.php');
 
// Maximum size for Automatic Gantt chart
DEFINE('MAX_GANTTIMG_SIZE_W',4000);
DEFINE('MAX_GANTTIMG_SIZE_H',5000);
 
// Scale Header types
DEFINE("GANTT_HDAY",1);
DEFINE("GANTT_HWEEK",2);
DEFINE("GANTT_HMONTH",4);
DEFINE("GANTT_HYEAR",8);
DEFINE("GANTT_HHOUR",16);
DEFINE("GANTT_HMIN",32);
 
// Bar patterns
DEFINE("GANTT_RDIAG",BAND_RDIAG); // Right diagonal lines
DEFINE("GANTT_LDIAG",BAND_LDIAG); // Left diagonal lines
DEFINE("GANTT_SOLID",BAND_SOLID); // Solid one color
DEFINE("GANTT_VLINE",BAND_VLINE); // Vertical lines
DEFINE("GANTT_HLINE",BAND_HLINE); // Horizontal lines
DEFINE("GANTT_3DPLANE",BAND_3DPLANE); // "3D" Plane
DEFINE("GANTT_HVCROSS",BAND_HVCROSS); // Vertical/Hor crosses
DEFINE("GANTT_DIAGCROSS",BAND_DIAGCROSS); // Diagonal crosses
 
// Conversion constant
DEFINE("SECPERDAY",3600*24);
 
// Locales. ONLY KEPT FOR BACKWARDS COMPATIBILITY
// You should use the proper locale strings directly
// from now on.
DEFINE("LOCALE_EN","en_UK");
DEFINE("LOCALE_SV","sv_SE");
 
// Layout of bars
DEFINE("GANTT_EVEN",1);
DEFINE("GANTT_FROMTOP",2);
 
// Style for minute header
DEFINE("MINUTESTYLE_MM",0); // 15
DEFINE("MINUTESTYLE_CUSTOM",2); // Custom format
 
 
// Style for hour header
DEFINE("HOURSTYLE_HM24",0); // 13:10
DEFINE("HOURSTYLE_HMAMPM",1); // 1:10pm
DEFINE("HOURSTYLE_H24",2); // 13
DEFINE("HOURSTYLE_HAMPM",3); // 1pm
DEFINE("HOURSTYLE_CUSTOM",4); // User defined
 
// Style for day header
DEFINE("DAYSTYLE_ONELETTER",0); // "M"
DEFINE("DAYSTYLE_LONG",1); // "Monday"
DEFINE("DAYSTYLE_LONGDAYDATE1",2); // "Monday 23 Jun"
DEFINE("DAYSTYLE_LONGDAYDATE2",3); // "Monday 23 Jun 2003"
DEFINE("DAYSTYLE_SHORT",4); // "Mon"
DEFINE("DAYSTYLE_SHORTDAYDATE1",5); // "Mon 23/6"
DEFINE("DAYSTYLE_SHORTDAYDATE2",6); // "Mon 23 Jun"
DEFINE("DAYSTYLE_SHORTDAYDATE3",7); // "Mon 23"
DEFINE("DAYSTYLE_SHORTDATE1",8); // "23/6"
DEFINE("DAYSTYLE_SHORTDATE2",9); // "23 Jun"
DEFINE("DAYSTYLE_SHORTDATE3",10); // "Mon 23"
DEFINE("DAYSTYLE_SHORTDATE4",11); // "23"
DEFINE("DAYSTYLE_CUSTOM",12); // "M"
 
// Styles for week header
DEFINE("WEEKSTYLE_WNBR",0);
DEFINE("WEEKSTYLE_FIRSTDAY",1);
DEFINE("WEEKSTYLE_FIRSTDAY2",2);
DEFINE("WEEKSTYLE_FIRSTDAYWNBR",3);
DEFINE("WEEKSTYLE_FIRSTDAY2WNBR",4);
 
// Styles for month header
DEFINE("MONTHSTYLE_SHORTNAME",0);
DEFINE("MONTHSTYLE_LONGNAME",1);
DEFINE("MONTHSTYLE_LONGNAMEYEAR2",2);
DEFINE("MONTHSTYLE_SHORTNAMEYEAR2",3);
DEFINE("MONTHSTYLE_LONGNAMEYEAR4",4);
DEFINE("MONTHSTYLE_SHORTNAMEYEAR4",5);
DEFINE("MONTHSTYLE_FIRSTLETTER",6);
 
 
// Types of constrain links
DEFINE('CONSTRAIN_STARTSTART',0);
DEFINE('CONSTRAIN_STARTEND',1);
DEFINE('CONSTRAIN_ENDSTART',2);
DEFINE('CONSTRAIN_ENDEND',3);
 
// Arrow direction for constrain links
DEFINE('ARROW_DOWN',0);
DEFINE('ARROW_UP',1);
DEFINE('ARROW_LEFT',2);
DEFINE('ARROW_RIGHT',3);
 
// Arrow type for constrain type
DEFINE('ARROWT_SOLID',0);
DEFINE('ARROWT_OPEN',1);
 
// Arrow size for constrain lines
DEFINE('ARROW_S1',0);
DEFINE('ARROW_S2',1);
DEFINE('ARROW_S3',2);
DEFINE('ARROW_S4',3);
DEFINE('ARROW_S5',4);
 
// Activity types for use with utility method CreateSimple()
DEFINE('ACTYPE_NORMAL',0);
DEFINE('ACTYPE_GROUP',1);
DEFINE('ACTYPE_MILESTONE',2);
 
DEFINE('ACTINFO_3D',1);
DEFINE('ACTINFO_2D',0);
 
 
// Check if array_fill() exists
if (!function_exists('array_fill')) {
function array_fill($iStart, $iLen, $vValue) {
$aResult = array();
for ($iCount = $iStart; $iCount < $iLen + $iStart; $iCount++) {
$aResult[$iCount] = $vValue;
}
return $aResult;
}
}
 
//===================================================
// CLASS GanttActivityInfo
// Description:
//===================================================
class GanttActivityInfo {
var $iColor='black';
var $iBackgroundColor='lightgray';
var $iFFamily=FF_FONT1,$iFStyle=FS_NORMAL,$iFSize=10,$iFontColor='black';
var $iTitles=array();
var $iWidth=array(),$iHeight=-1;
var $iLeftColMargin=4,$iRightColMargin=1,$iTopColMargin=1,$iBottomColMargin=3;
var $iTopHeaderMargin = 4;
var $vgrid = null;
var $iStyle=1;
var $iShow=true;
var $iHeaderAlign='center';
 
function GanttActivityInfo() {
$this->vgrid = new LineProperty();
}
 
function Hide($aF=true) {
$this->iShow=!$aF;
}
 
function Show($aF=true) {
$this->iShow=$aF;
}
 
// Specify font
function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) {
$this->iFFamily = $aFFamily;
$this->iFStyle = $aFStyle;
$this->iFSize = $aFSize;
}
 
function SetStyle($aStyle) {
$this->iStyle = $aStyle;
}
 
function SetColumnMargin($aLeft,$aRight) {
$this->iLeftColMargin = $aLeft;
$this->iRightColMargin = $aRight;
}
 
function SetFontColor($aFontColor) {
$this->iFontColor = $aFontColor;
}
 
function SetColor($aColor) {
$this->iColor = $aColor;
}
 
function SetBackgroundColor($aColor) {
$this->iBackgroundColor = $aColor;
}
 
function SetColTitles($aTitles,$aWidth=null) {
$this->iTitles = $aTitles;
$this->iWidth = $aWidth;
}
 
function SetMinColWidth($aWidths) {
$n = min(count($this->iTitles),count($aWidths));
for($i=0; $i < $n; ++$i ) {
if( !empty($aWidths[$i]) ) {
if( empty($this->iWidth[$i]) ) {
$this->iWidth[$i] = $aWidths[$i];
}
else {
$this->iWidth[$i] = max($this->iWidth[$i],$aWidths[$i]);
}
}
}
}
 
function GetWidth(&$aImg) {
$txt = new TextProperty();
$txt->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
$n = count($this->iTitles) ;
$rm=$this->iRightColMargin;
$w = 0;
for($h=0, $i=0; $i < $n; ++$i ) {
$w += $this->iLeftColMargin;
$txt->Set($this->iTitles[$i]);
if( !empty($this->iWidth[$i]) ) {
$w1 = max($txt->GetWidth($aImg)+$rm,$this->iWidth[$i]);
}
else {
$w1 = $txt->GetWidth($aImg)+$rm;
}
$this->iWidth[$i] = $w1;
$w += $w1;
$h = max($h,$txt->GetHeight($aImg));
}
$this->iHeight = $h+$this->iTopHeaderMargin;
$txt='';
return $w;
}
function GetColStart(&$aImg,&$ioStart,$aAddLeftMargin=false) {
$n = count($this->iTitles) ;
$adj = $aAddLeftMargin ? $this->iLeftColMargin : 0;
$ioStart=array($aImg->left_margin+$adj);
for( $i=1; $i < $n; ++$i ) {
$ioStart[$i] = $ioStart[$i-1]+$this->iLeftColMargin+$this->iWidth[$i-1];
}
}
// Adjust headers left, right or centered
function SetHeaderAlign($aAlign) {
$this->iHeaderAlign=$aAlign;
}
 
function Stroke(&$aImg,$aXLeft,$aYTop,$aXRight,$aYBottom,$aUseTextHeight=false) {
 
if( !$this->iShow ) return;
 
$txt = new TextProperty();
$txt->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
$txt->SetColor($this->iFontColor);
$txt->SetAlign($this->iHeaderAlign,'top');
$n=count($this->iTitles);
 
if( $n == 0 )
return;
$x = $aXLeft;
$h = $this->iHeight;
$yTop = $aUseTextHeight ? $aYBottom-$h-$this->iTopColMargin-$this->iBottomColMargin : $aYTop ;
 
if( $h < 0 ) {
JpGraphError::RaiseL(6001);
//('Internal error. Height for ActivityTitles is < 0');
}
 
$aImg->SetLineWeight(1);
// Set background color
$aImg->SetColor($this->iBackgroundColor);
$aImg->FilledRectangle($aXLeft,$yTop,$aXRight,$aYBottom-1);
 
if( $this->iStyle == 1 ) {
// Make a 3D effect
$aImg->SetColor('white');
$aImg->Line($aXLeft,$yTop+1,
$aXRight,$yTop+1);
}
for($i=0; $i < $n; ++$i ) {
if( $this->iStyle == 1 ) {
// Make a 3D effect
$aImg->SetColor('white');
$aImg->Line($x+1,$yTop,$x+1,$aYBottom);
}
$x += $this->iLeftColMargin;
$txt->Set($this->iTitles[$i]);
// Adjust the text anchor position according to the choosen alignment
$xp = $x;
if( $this->iHeaderAlign == 'center' ) {
$xp = (($x-$this->iLeftColMargin)+($x+$this->iWidth[$i]))/2;
}
elseif( $this->iHeaderAlign == 'right' ) {
$xp = $x +$this->iWidth[$i]-$this->iRightColMargin;
}
$txt->Stroke($aImg,$xp,$yTop+$this->iTopHeaderMargin);
$x += $this->iWidth[$i];
if( $i < $n-1 ) {
$aImg->SetColor($this->iColor);
$aImg->Line($x,$yTop,$x,$aYBottom);
}
}
 
$aImg->SetColor($this->iColor);
$aImg->Line($aXLeft,$yTop, $aXRight,$yTop);
 
// Stroke vertical column dividers
$cols=array();
$this->GetColStart($aImg,$cols);
$n=count($cols);
for( $i=1; $i < $n; ++$i ) {
$this->vgrid->Stroke($aImg,$cols[$i],$aYBottom,$cols[$i],
$aImg->height - $aImg->bottom_margin);
}
}
}
 
 
//===================================================
// CLASS GanttGraph
// Description: Main class to handle gantt graphs
//===================================================
class GanttGraph extends Graph {
var $scale; // Public accessible
var $iObj=array(); // Gantt objects
var $iLabelHMarginFactor=0.2; // 10% margin on each side of the labels
var $iLabelVMarginFactor=0.4; // 40% margin on top and bottom of label
var $iLayout=GANTT_FROMTOP; // Could also be GANTT_EVEN
var $iSimpleFont = FF_FONT1,$iSimpleFontSize=11;
var $iSimpleStyle=GANTT_RDIAG,$iSimpleColor='yellow',$iSimpleBkgColor='red';
var $iSimpleProgressBkgColor='gray',$iSimpleProgressColor='darkgreen';
var $iSimpleProgressStyle=GANTT_SOLID;
var $hgrid=null;
//---------------
// CONSTRUCTOR
// Create a new gantt graph
function GanttGraph($aWidth=0,$aHeight=0,$aCachedName="",$aTimeOut=0,$aInline=true) {
 
// Backward compatibility
if( $aWidth == -1 ) $aWidth=0;
if( $aHeight == -1 ) $aHeight=0;
 
if( $aWidth< 0 || $aHeight < 0 ) {
JpgraphError::RaiseL(6002);
//("You can't specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension.");
}
Graph::Graph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline);
$this->scale = new GanttScale($this->img);
 
// Default margins
$this->img->SetMargin(15,17,25,15);
 
$this->hgrid = new HorizontalGridLine();
$this->scale->ShowHeaders(GANTT_HWEEK|GANTT_HDAY);
$this->SetBox();
}
//---------------
// PUBLIC METHODS
 
//
 
function SetSimpleFont($aFont,$aSize) {
$this->iSimpleFont = $aFont;
$this->iSimpleFontSize = $aSize;
}
 
function SetSimpleStyle($aBand,$aColor,$aBkgColor) {
$this->iSimpleStyle = $aBand;
$this->iSimpleColor = $aColor;
$this->iSimpleBkgColor = $aBkgColor;
}
 
// A utility function to help create basic Gantt charts
function CreateSimple($data,$constrains=array(),$progress=array()) {
$num = count($data);
for( $i=0; $i < $num; ++$i) {
switch( $data[$i][1] ) {
case ACTYPE_GROUP:
// Create a slightly smaller height bar since the
// "wings" at the end will make it look taller
$a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',8);
$a->title->SetFont($this->iSimpleFont,FS_BOLD,$this->iSimpleFontSize);
$a->rightMark->Show();
$a->rightMark->SetType(MARK_RIGHTTRIANGLE);
$a->rightMark->SetWidth(8);
$a->rightMark->SetColor('black');
$a->rightMark->SetFillColor('black');
$a->leftMark->Show();
$a->leftMark->SetType(MARK_LEFTTRIANGLE);
$a->leftMark->SetWidth(8);
$a->leftMark->SetColor('black');
$a->leftMark->SetFillColor('black');
$a->SetPattern(BAND_SOLID,'black');
$csimpos = 6;
break;
case ACTYPE_NORMAL:
$a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',10);
$a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize);
$a->SetPattern($this->iSimpleStyle,$this->iSimpleColor);
$a->SetFillColor($this->iSimpleBkgColor);
// Check if this activity should have a constrain line
$n = count($constrains);
for( $j=0; $j < $n; ++$j ) {
if( empty($constrains[$j]) || (count($constrains[$j]) != 3) ) {
JpGraphError::RaiseL(6003,$j);
//("Invalid format for Constrain parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)");
}
if( $constrains[$j][0]==$data[$i][0] ) {
$a->SetConstrain($constrains[$j][1],$constrains[$j][2],'black',ARROW_S2,ARROWT_SOLID);
}
}
 
// Check if this activity have a progress bar
$n = count($progress);
for( $j=0; $j < $n; ++$j ) {
if( empty($progress[$j]) || (count($progress[$j]) != 2) ) {
JpGraphError::RaiseL(6004,$j);
//("Invalid format for Progress parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)");
}
if( $progress[$j][0]==$data[$i][0] ) {
$a->progress->Set($progress[$j][1]);
$a->progress->SetHeight(0.5);
$a->progress->SetPattern($this->iSimpleProgressStyle,
$this->iSimpleProgressColor);
$a->progress->SetFillColor($this->iSimpleProgressBkgColor);
//$a->progress->SetPattern($progress[$j][2],$progress[$j][3]);
break;
}
}
$csimpos = 6;
break;
 
case ACTYPE_MILESTONE:
$a = new MileStone($data[$i][0],$data[$i][2],$data[$i][3]);
$a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize);
$a->caption->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize);
$csimpos = 5;
break;
default:
die('Unknown activity type');
break;
}
 
// Setup caption
$a->caption->Set($data[$i][$csimpos-1]);
 
// Check if this activity should have a CSIM targetĀ ?
if( !empty($data[$i][$csimpos]) ) {
$a->SetCSIMTarget($data[$i][$csimpos]);
$a->SetCSIMAlt($data[$i][$csimpos+1]);
}
if( !empty($data[$i][$csimpos+2]) ) {
$a->title->SetCSIMTarget($data[$i][$csimpos+2]);
$a->title->SetCSIMAlt($data[$i][$csimpos+3]);
}
 
$this->Add($a);
}
}
 
// Set what headers should be shown
function ShowHeaders($aFlg) {
$this->scale->ShowHeaders($aFlg);
}
// Specify the fraction of the font height that should be added
// as vertical margin
function SetLabelVMarginFactor($aVal) {
$this->iLabelVMarginFactor = $aVal;
}
 
// Synonym to the method above
function SetVMarginFactor($aVal) {
$this->iLabelVMarginFactor = $aVal;
}
// Add a new Gantt object
function Add($aObject) {
if( is_array($aObject) && count($aObject) > 0 ) {
$cl = $aObject[0];
if( is_a($cl,'IconPlot') ) {
$this->AddIcon($aObject);
}
else {
$n = count($aObject);
for($i=0; $i < $n; ++$i)
$this->iObj[] = $aObject[$i];
}
}
else {
if( is_a($aObject,'IconPlot') ) {
$this->AddIcon($aObject);
}
else {
$this->iObj[] = $aObject;
}
}
}
 
// Override inherit method from Graph and give a warning message
function SetScale() {
JpGraphError::RaiseL(6005);
//("SetScale() is not meaningfull with Gantt charts.");
}
 
// Specify the date range for Gantt graphs (if this is not set it will be
// automtically determined from the input data)
function SetDateRange($aStart,$aEnd) {
// Adjust the start and end so that the indicate the
// begining and end of respective start and end days
if( strpos($aStart,':') === false )
$aStart = date('Y-m-d 00:00',strtotime($aStart));
if( strpos($aEnd,':') === false )
$aEnd = date('Y-m-d 23:59',strtotime($aEnd));
$this->scale->SetRange($aStart,$aEnd);
}
// Get the maximum width of the activity titles columns for the bars
// The name is lightly misleading since we from now on can have
// multiple columns in the label section. When this was first written
// it only supported a single label, hence the name.
function GetMaxLabelWidth() {
$m=50;
if( $this->iObj != null ) {
$marg = $this->scale->actinfo->iLeftColMargin+$this->scale->actinfo->iRightColMargin;
$m = $this->iObj[0]->title->GetWidth($this->img)+$marg;
$n = count($this->iObj);
for($i=1; $i < $n; ++$i) {
if( !empty($this->iObj[$i]->title) ) {
if( $this->iObj[$i]->title->HasTabs() ) {
list($tot,$w) = $this->iObj[$i]->title->GetWidth($this->img,true);
$m=max($m,$tot);
}
else
$m=max($m,$this->iObj[$i]->title->GetWidth($this->img));
}
}
}
return $m;
}
// Get the maximum height of the titles for the bars
function GetMaxLabelHeight() {
$m=0;
if( $this->iObj != null ) {
$m = $this->iObj[0]->title->GetHeight($this->img);
$n = count($this->iObj);
for($i=1; $i < $n; ++$i) {
if( !empty($this->iObj[$i]->title) ) {
$m=max($m,$this->iObj[$i]->title->GetHeight($this->img));
}
}
}
return $m;
}
 
function GetMaxBarAbsHeight() {
$m=0;
if( $this->iObj != null ) {
$m = $this->iObj[0]->GetAbsHeight($this->img);
$n = count($this->iObj);
for($i=1; $i < $n; ++$i) {
$m=max($m,$this->iObj[$i]->GetAbsHeight($this->img));
}
}
return $m;
}
// Get the maximum used line number (vertical position) for bars
function GetBarMaxLineNumber() {
$m=0;
if( $this->iObj != null ) {
$m = $this->iObj[0]->GetLineNbr();
$n = count($this->iObj);
for($i=1; $i < $n; ++$i) {
$m=max($m,$this->iObj[$i]->GetLineNbr());
}
}
return $m;
}
// Get the minumum and maximum used dates for all bars
function GetBarMinMax() {
$start = 0 ;
$n = count($this->iObj);
 
while( $start < $n && $this->iObj[$start]->GetMaxDate() === false )
++$start;
if( $start >= $n ) {
JpgraphError::RaiseL(6006);
//('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]');
}
 
$max=$this->scale->NormalizeDate($this->iObj[$start]->GetMaxDate());
$min=$this->scale->NormalizeDate($this->iObj[$start]->GetMinDate());
 
for($i=$start+1; $i < $n; ++$i) {
$rmax = $this->scale->NormalizeDate($this->iObj[$i]->GetMaxDate());
if( $rmax != false )
$max=Max($max,$rmax);
$rmin = $this->scale->NormalizeDate($this->iObj[$i]->GetMinDate());
if( $rmin != false )
$min=Min($min,$rmin);
}
$minDate = date("Y-m-d",$min);
$min = strtotime($minDate);
$maxDate = date("Y-m-d 23:59",$max);
$max = strtotime($maxDate);
return array($min,$max);
}
 
// Create a new auto sized canvas if the user hasn't specified a size
// The size is determined by what scale the user has choosen and hence
// the minimum width needed to display the headers. Some margins are
// also added to make it better looking.
function AutoSize() {
if( $this->img->img == null ) {
// The predefined left, right, top, bottom margins.
// Note that the top margin might incease depending on
// the title.
$lm = $this->img->left_margin;
$rm = $this->img->right_margin;
$rm += 2 ;
$tm = $this->img->top_margin;
$bm = $this->img->bottom_margin;
$bm += 1;
if( BRAND_TIMING ) $bm += 10;
// First find out the height
$n=$this->GetBarMaxLineNumber()+1;
$m=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight());
$height=$n*((1+$this->iLabelVMarginFactor)*$m);
// Add the height of the scale titles
$h=$this->scale->GetHeaderHeight();
$height += $h;
 
// Calculate the top margin needed for title and subtitle
if( $this->title->t != "" ) {
$tm += $this->title->GetFontHeight($this->img);
}
if( $this->subtitle->t != "" ) {
$tm += $this->subtitle->GetFontHeight($this->img);
}
 
// ...and then take the bottom and top plot margins into account
$height += $tm + $bm + $this->scale->iTopPlotMargin + $this->scale->iBottomPlotMargin;
// Now find the minimum width for the chart required
 
// If day scale or smaller is shown then we use the day font width
// as the base size unit.
// If only weeks or above is displayed we use a modified unit to
// get a smaller image.
if( $this->scale->IsDisplayHour() || $this->scale->IsDisplayMinute() ) {
// Add 2 pixel margin on each side
$fw=$this->scale->day->GetFontWidth($this->img)+4;
}
elseif( $this->scale->IsDisplayWeek() ) {
$fw = 8;
}
elseif( $this->scale->IsDisplayMonth() ) {
$fw = 4;
}
else {
$fw = 2;
}
 
$nd=$this->scale->GetNumberOfDays();
 
if( $this->scale->IsDisplayDay() ) {
// If the days are displayed we also need to figure out
// how much space each day's title will require.
switch( $this->scale->day->iStyle ) {
case DAYSTYLE_LONG :
$txt = "Monday";
break;
case DAYSTYLE_LONGDAYDATE1 :
$txt = "Monday 23 Jun";
break;
case DAYSTYLE_LONGDAYDATE2 :
$txt = "Monday 23 Jun 2003";
break;
case DAYSTYLE_SHORT :
$txt = "Mon";
break;
case DAYSTYLE_SHORTDAYDATE1 :
$txt = "Mon 23/6";
break;
case DAYSTYLE_SHORTDAYDATE2 :
$txt = "Mon 23 Jun";
break;
case DAYSTYLE_SHORTDAYDATE3 :
$txt = "Mon 23";
break;
case DAYSTYLE_SHORTDATE1 :
$txt = "23/6";
break;
case DAYSTYLE_SHORTDATE2 :
$txt = "23 Jun";
break;
case DAYSTYLE_SHORTDATE3 :
$txt = "Mon 23";
break;
case DAYSTYLE_SHORTDATE4 :
$txt = "88";
break;
case DAYSTYLE_CUSTOM :
$txt = date($this->scale->day->iLabelFormStr,
strtotime('2003-12-20 18:00'));
break;
case DAYSTYLE_ONELETTER :
default:
$txt = "M";
break;
}
$fw = $this->scale->day->GetStrWidth($this->img,$txt)+6;
}
 
// If we have hours enabled we must make sure that each day has enough
// space to fit the number of hours to be displayed.
if( $this->scale->IsDisplayHour() ) {
// Depending on what format the user has choose we need different amount
// of space. We therefore create a typical string for the choosen format
// and determine the length of that string.
switch( $this->scale->hour->iStyle ) {
case HOURSTYLE_HMAMPM:
$txt = '12:00pm';
break;
case HOURSTYLE_H24:
// 13
$txt = '24';
break;
case HOURSTYLE_HAMPM:
$txt = '12pm';
break;
case HOURSTYLE_CUSTOM:
$txt = date($this->scale->hour->iLabelFormStr,strtotime('2003-12-20 18:00'));
break;
case HOURSTYLE_HM24:
default:
$txt = '24:00';
break;
}
 
$hfw = $this->scale->hour->GetStrWidth($this->img,$txt)+6;
$mw = $hfw;
if( $this->scale->IsDisplayMinute() ) {
// Depending on what format the user has choose we need different amount
// of space. We therefore create a typical string for the choosen format
// and determine the length of that string.
switch( $this->scale->minute->iStyle ) {
case HOURSTYLE_CUSTOM:
$txt2 = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55'));
break;
case MINUTESTYLE_MM:
default:
$txt2 = '15';
break;
}
$mfw = $this->scale->minute->GetStrWidth($this->img,$txt2)+6;
$n2 = ceil(60 / $this->scale->minute->GetIntervall() );
$mw = $n2 * $mfw;
}
$hfw = $hfw < $mw ? $mw : $hfw ;
$n = ceil(24*60 / $this->scale->TimeToMinutes($this->scale->hour->GetIntervall()) );
$hw = $n * $hfw;
$fw = $fw < $hw ? $hw : $fw ;
}
 
// We need to repeat this code block here as well.
// THIS iS NOT A MISTAKE !
// We really need it since we need to adjust for minutes both in the case
// where hour scale is shown and when it is not shown.
 
if( $this->scale->IsDisplayMinute() ) {
// Depending on what format the user has choose we need different amount
// of space. We therefore create a typical string for the choosen format
// and determine the length of that string.
switch( $this->scale->minute->iStyle ) {
case HOURSTYLE_CUSTOM:
$txt = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55'));
break;
case MINUTESTYLE_MM:
default:
$txt = '15';
break;
}
$mfw = $this->scale->minute->GetStrWidth($this->img,$txt)+6;
$n = ceil(60 / $this->scale->TimeToMinutes($this->scale->minute->GetIntervall()) );
$mw = $n * $mfw;
$fw = $fw < $mw ? $mw : $fw ;
}
 
// If we display week we must make sure that 7*$fw is enough
// to fit up to 10 characters of the week font (if the week is enabled)
if( $this->scale->IsDisplayWeek() ) {
// Depending on what format the user has choose we need different amount
// of space
$fsw = strlen($this->scale->week->iLabelFormStr);
if( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) {
$fsw += 8;
}
elseif( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ) {
$fsw += 7;
}
else {
$fsw += 4;
}
$ww = $fsw*$this->scale->week->GetFontWidth($this->img);
if( 7*$fw < $ww ) {
$fw = ceil($ww/7);
}
}
 
if( !$this->scale->IsDisplayDay() && !$this->scale->IsDisplayHour() &&
!( ($this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ||
$this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR) && $this->scale->IsDisplayWeek() ) ) {
// If we don't display the individual days we can shrink the
// scale a little bit. This is a little bit pragmatic at the
// moment and should be re-written to take into account
// a) What scales exactly are shown and
// b) what format do they use so we know how wide we need to
// make each scale text space at minimum.
$fw /= 2;
if( !$this->scale->IsDisplayWeek() ) {
$fw /= 1.8;
}
}
 
$cw = $this->GetMaxActInfoColWidth() ;
$this->scale->actinfo->SetMinColWidth($cw);
if( $this->img->width <= 0 ) {
// Now determine the width for the activity titles column
 
// Firdst find out the maximum width of each object column
$titlewidth = max(max($this->GetMaxLabelWidth(),
$this->scale->tableTitle->GetWidth($this->img)),
$this->scale->actinfo->GetWidth($this->img));
 
// Add the width of the vertivcal divider line
$titlewidth += $this->scale->divider->iWeight*2;
 
 
// Now get the total width taking
// titlewidth, left and rigt margin, dayfont size
// into account
$width = $titlewidth + $nd*$fw + $lm+$rm;
}
else {
$width = $this->img->width;
}
 
$width = round($width);
$height = round($height);
if( $width > MAX_GANTTIMG_SIZE_W || $height > MAX_GANTTIMG_SIZE_H ) {
JpgraphError::RaiseL(6007,$width,$height);
//("Sanity check for automatic Gantt chart size failed. Either the width (=$width) or height (=$height) is larger than MAX_GANTTIMG_SIZE. This could potentially be caused by a wrong date in one of the activities.");
}
$this->img->CreateImgCanvas($width,$height);
$this->img->SetMargin($lm,$rm,$tm,$bm);
}
}
 
// Return an array width the maximum width for each activity
// column. This is used when we autosize the columns where we need
// to find out the maximum width of each column. In order to do that we
// must walk through all the objects, sigh...
function GetMaxActInfoColWidth() {
$n = count($this->iObj);
if( $n == 0 ) return;
$w = array();
$m = $this->scale->actinfo->iLeftColMargin + $this->scale->actinfo->iRightColMargin;
for( $i=0; $i < $n; ++$i ) {
$tmp = $this->iObj[$i]->title->GetColWidth($this->img,$m);
$nn = count($tmp);
for( $j=0; $j < $nn; ++$j ) {
if( empty($w[$j]) )
$w[$j] = $tmp[$j];
else
$w[$j] = max($w[$j],$tmp[$j]);
}
}
return $w;
}
 
// Stroke the gantt chart
function Stroke($aStrokeFileName="") {
 
 
// 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);
 
// Should we autoscale dates?
if( !$this->scale->IsRangeSet() ) {
list($min,$max) = $this->GetBarMinMax();
$this->scale->SetRange($min,$max);
}
 
$this->scale->AdjustStartEndDay();
 
// Check if we should autoscale the image
$this->AutoSize();
// Should we start from the top or just spread the bars out even over the
// available height
$this->scale->SetVertLayout($this->iLayout);
if( $this->iLayout == GANTT_FROMTOP ) {
$maxheight=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight());
$this->scale->SetVertSpacing($maxheight*(1+$this->iLabelVMarginFactor));
}
// If it hasn't been set find out the maximum line number
if( $this->scale->iVertLines == -1 )
$this->scale->iVertLines = $this->GetBarMaxLineNumber()+1;
$maxwidth=max($this->scale->actinfo->GetWidth($this->img),
max($this->GetMaxLabelWidth(),
$this->scale->tableTitle->GetWidth($this->img)));
 
$this->scale->SetLabelWidth($maxwidth+$this->scale->divider->iWeight);//*(1+$this->iLabelHMarginFactor));
 
if( !$_csim ) {
$this->StrokePlotArea();
if( $this->iIconDepth == DEPTH_BACK ) {
$this->StrokeIcons();
}
}
 
$this->scale->Stroke();
 
if( !$_csim ) {
// Due to a minor off by 1 bug we need to temporarily adjust the margin
$this->img->right_margin--;
$this->StrokePlotBox();
$this->img->right_margin++;
}
 
// Stroke Grid line
$this->hgrid->Stroke($this->img,$this->scale);
 
$n = count($this->iObj);
for($i=0; $i < $n; ++$i) {
//$this->iObj[$i]->SetLabelLeftMargin(round($maxwidth*$this->iLabelHMarginFactor/2));
$this->iObj[$i]->Stroke($this->img,$this->scale);
}
 
$this->StrokeTitles();
 
if( !$_csim ) {
$this->StrokeConstrains();
$this->footer->Stroke($this->img);
 
if( $this->iIconDepth == DEPTH_FRONT) {
$this->StrokeIcons();
}
 
// 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 "__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);
}
}
}
 
function StrokeConstrains() {
$n = count($this->iObj);
 
// Stroke all constrains
for($i=0; $i < $n; ++$i) {
 
// Some gantt objects may not have constraints associated with them
// for example we can add IconPlots which doesn't have this property.
if( empty($this->iObj[$i]->constraints) ) continue;
 
$numConstrains = count($this->iObj[$i]->constraints);
 
for( $k = 0; $k < $numConstrains; $k++ ) {
$vpos = $this->iObj[$i]->constraints[$k]->iConstrainRow;
if( $vpos >= 0 ) {
$c1 = $this->iObj[$i]->iConstrainPos;
 
// Find out which object is on the target row
$targetobj = -1;
for( $j=0; $j < $n && $targetobj == -1; ++$j ) {
if( $this->iObj[$j]->iVPos == $vpos ) {
$targetobj = $j;
}
}
if( $targetobj == -1 ) {
JpGraphError::RaiseL(6008,$this->iObj[$i]->iVPos,$vpos);
//('You have specifed a constrain from row='.$this->iObj[$i]->iVPos.' to row='.$vpos.' which does not have any activity.');
}
$c2 = $this->iObj[$targetobj]->iConstrainPos;
if( count($c1) == 4 && count($c2 ) == 4) {
switch( $this->iObj[$i]->constraints[$k]->iConstrainType ) {
case CONSTRAIN_ENDSTART:
if( $c1[1] < $c2[1] ) {
$link = new GanttLink($c1[2],$c1[3],$c2[0],$c2[1]);
}
else {
$link = new GanttLink($c1[2],$c1[1],$c2[0],$c2[3]);
}
$link->SetPath(3);
break;
case CONSTRAIN_STARTEND:
if( $c1[1] < $c2[1] ) {
$link = new GanttLink($c1[0],$c1[3],$c2[2],$c2[1]);
}
else {
$link = new GanttLink($c1[0],$c1[1],$c2[2],$c2[3]);
}
$link->SetPath(0);
break;
case CONSTRAIN_ENDEND:
if( $c1[1] < $c2[1] ) {
$link = new GanttLink($c1[2],$c1[3],$c2[2],$c2[1]);
}
else {
$link = new GanttLink($c1[2],$c1[1],$c2[2],$c2[3]);
}
$link->SetPath(1);
break;
case CONSTRAIN_STARTSTART:
if( $c1[1] < $c2[1] ) {
$link = new GanttLink($c1[0],$c1[3],$c2[0],$c2[1]);
}
else {
$link = new GanttLink($c1[0],$c1[1],$c2[0],$c2[3]);
}
$link->SetPath(3);
break;
default:
JpGraphError::RaiseL(6009,$this->iObj[$i]->iVPos,$vpos);
//('Unknown constrain type specified from row='.$this->iObj[$i]->iVPos.' to row='.$vpos);
break;
}
 
$link->SetColor($this->iObj[$i]->constraints[$k]->iConstrainColor);
$link->SetArrow($this->iObj[$i]->constraints[$k]->iConstrainArrowSize,
$this->iObj[$i]->constraints[$k]->iConstrainArrowType);
$link->Stroke($this->img);
}
}
}
}
}
 
function GetCSIMAreas() {
if( !$this->iHasStroked )
$this->Stroke(_CSIM_SPECIALFILE);
 
$csim = $this->title->GetCSIMAreas();
$csim .= $this->subtitle->GetCSIMAreas();
$csim .= $this->subsubtitle->GetCSIMAreas();
 
$n = count($this->iObj);
for( $i=$n-1; $i >= 0; --$i )
$csim .= $this->iObj[$i]->GetCSIMArea();
return $csim;
}
}
 
//===================================================
// CLASS PredefIcons
// Description: Predefined icons for use with Gantt charts
//===================================================
DEFINE('GICON_WARNINGRED',0);
DEFINE('GICON_TEXT',1);
DEFINE('GICON_ENDCONS',2);
DEFINE('GICON_MAIL',3);
DEFINE('GICON_STARTCONS',4);
DEFINE('GICON_CALC',5);
DEFINE('GICON_MAGNIFIER',6);
DEFINE('GICON_LOCK',7);
DEFINE('GICON_STOP',8);
DEFINE('GICON_WARNINGYELLOW',9);
DEFINE('GICON_FOLDEROPEN',10);
DEFINE('GICON_FOLDER',11);
DEFINE('GICON_TEXTIMPORTANT',12);
 
class PredefIcons {
var $iBuiltinIcon = null;
var $iLen = -1 ;
 
function GetLen() {
return $this->iLen ;
}
 
function GetImg($aIdx) {
if( $aIdx < 0 || $aIdx >= $this->iLen ) {
JpGraphError::RaiseL(6010,$aIdx);
//('Illegal icon index for Gantt builtin icon ['.$aIdx.']');
}
return Image::CreateFromString(base64_decode($this->iBuiltinIcon[$aIdx][1]));
}
 
function PredefIcons() {
//==========================================================
// warning.png
//==========================================================
$this->iBuiltinIcon[0][0]= 1043 ;
$this->iBuiltinIcon[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'.
'B3RJTUUH0wgKFSgilWPhUQAAA6BJREFUeNrtl91rHFUYh5/3zMx+Z5JNUoOamCZNaqTZ6IWIkqRiQWmi1IDetHfeiCiltgXBP8AL'.
'0SIUxf/AvfRSBS9EKILFFqyIH9CEmFZtPqrBJLs7c+b1YneT3WTTbNsUFPLCcAbmzPt73o9zzgzs2Z793231UOdv3w9k9Z2uzOdA'.
'5+2+79yNeL7Hl7hw7oeixRMZ6PJM26W18DNAm/Vh7lR8fqh97NmMF11es1iFpMATqdirwMNA/J4DpIzkr5YsAF1PO6gIMYHRdPwl'.
'oO2elmB+qH3sm7XozbkgYvy8SzYnZPtcblyM6I+5z3jQ+0vJfgpEu56BfI9vUkbyi2HZd1QJoeWRiAjBd4SDCW8SSAOy6wBHMzF7'.
'YdV2A+ROuvRPLfHoiSU0EMY/cDAIhxJeGngKaN1VgHyPL7NBxI1K9P4QxBzw3K1zJ/zkG8B9uwaQ7/HNsRZv9kohBGD0o7JqMYS/'.
'/ynPidQw/LrBiPBcS/yFCT95DvB2BWAy4575PaQbQKW+tPd3GCItu2odKI++YxiKu0d26oWmAD7paZU/rLz37VqIijD2YbnzNBBE'.
'IBHf8K8qjL7vYhCGErEU8CTg3xXAeMp96GrJEqkyXkm9Bhui1xfsunjdGhcYLq+IzjsGmBt5YH/cmJkFq6gIqlon3u4LxdKGuCIo'.
'Qu41g0E41po+2R33Xt5uz9kRIB2UTle7PnfKrROP1HD4sRjZlq0lzhwoZ6rDNeTi3nEg1si/7FT7kYQbXS6E5E65tA5uRF9tutq0'.
'K/VwAF+/FbIYWt6+tjQM/AqUms7A4Wy6d7YSfSNxgMmzi0ycWWworio4QJvj4LpuL5BqugTnXzzqJsJwurrlNhJXFaavW67NRw3F'.
'q+aJcCQVe9fzvJGmAY7/dPH0gi0f64OveGxa+usCuQMeZ0+kt8BVrX+qPO9Bzx0MgqBvs+a2PfDdYIf+WAjXU1ub4tqNaPPzRs8A'.
'blrli+WVn79cXn0cWKl+tGx7HLc7pu3CSmnfitL+l1UihAhwjFkPQev4K/fSABjBM8JCaFuurJU+rgW41SroA8aNMVNAFtgHJCsn'.
'XGy/58QVxAC9MccJtZ5kIzNlW440WrJ2ea4YPA9cAooA7i0A/gS+iqLoOpB1HOegqrYB3UBmJrAtQAJwpwPr1Ry92wVlgZsiYlW1'.
'uX1gU36dymgqYxJIJJNJT1W9QqHgNwFQBGYqo94OwHZQUuPD7ACglSvc+5n5T9m/wfJJX4U9qzEAAAAASUVORK5CYII=' ;
 
//==========================================================
// edit.png
//==========================================================
$this->iBuiltinIcon[1][0]= 959 ;
$this->iBuiltinIcon[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAFgAWABY9j+ZuwAAAAlwSFlz'.
'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDAwbIEXOA6AAAAM8SURBVHicpdRPaBxlHMbx76ZvsmOTmm1dsEqQSIIsEmGVBAQjivEQ'.
'PAUJngpWsAWlBw8egpQepKwplN4ULEG9CjkEyUFKlSJrWTG0IU51pCsdYW2ncUPjdtp9Z+f3vuNhu8nKbmhaf5cZeGc+PO8zf1Lc'.
'm0KhkACICCKCMeaBjiLC0tLSnjNvPmuOHRpH0TZTU1M8zBi9wakzn7OFTs5sw8YYACYmJrre7HkeuVyu69qPF77hlT1XmZ0eQ03O'.
'wOLJTvhBx1rLz18VmJ0eY+jVd2FxDkKXnvYLHgb97OgLzE4ON9Hzc1B1QaQzsed5O0Lta3Ec89OnR5h5McfQ+Mw2qgQUnfBOPbZ3'.
'bK3l+xOvMT0+3ERLp5FNF6UEjcL32+DdVmGt5WLhDYYPZrbRqreFumXwql0S3w9tnDvLWD5PZigPpdOwuYpSCo3C8wU3UHxQdHbf'.
'cZIkNM6dxcnlUM4k1eUFMlUPpUADbpkttFarHe6oYqeOr6yt4RzMQHYUcUsQVtGicHDwKprViuLDkkOtVnsHCHZVRVy/zcj1i5Af'.
'h8AjdIts+hUcGcYPK3iBtKM3gD/uAzf/AdY2mmmVgy6X8YNNKmGIvyloPcB8SUin07RQ4EZHFdsdG0wkJEnEaHAJxvKEpSLeaokV'.
'r4zWmhUZYLlY4b1D03y5eIEWCtS7vsciAgiIxkQRabWOrlQor66y4pUphoJb1jiO4uO5o0S3q6RSqVbiOmC7VCEgAhLSaDQ48dH7'.
'vD46REY0iysegSjKQciRt99ib7qXwX0O+pG4teM6YKHLB9JMq4mTmF9/+AKA4wvLZByH7OgYL7+UY2qvw/7Bfg5kHiXjJFyv3CGO'.
'Y1rof+BW4t/XLiPG0DCGr79d4XzRxRnIMn98huXSTYyJ6et1UNYQhRvcinpJq86H3wGPPPM0iBDd+QffD1g4eZjLvuG7S1Wef26E'.
'J7L7eSx7gAHVg7V3MSbi6m/r93baBd6qQjerAJg/9Ql/XrvG0ON1+vv7GH3qSfY5fahUnSTpwZgIEQesaVXRPbHRG/xyJSAxMYlp'.
'EOm71HUINiY7mGb95l/8jZCyQmJjMDGJjUmsdCROtZ0n/P/Z8v4Fs2MTUUf7vYoAAAAASUVORK5CYII=' ;
 
//==========================================================
// endconstrain.png
//==========================================================
$this->iBuiltinIcon[2][0]= 666 ;
$this->iBuiltinIcon[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'.
'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ALEREILkh0+eQAAAIXSURBVHictZU9aFNRFMd/N81HX77aptJUWmp1LHRpIcWhg5sIDlUQ'.
'LAXB4t7RRUpwEhy7iQ46CCIoSHcl0CFaoVARU2MFMYktadLXJNok7x2HtCExvuYFmnO4w/3gx+Gc/z1HKRTdMEdXqHbB/sgc/sic'.
'nDoYAI8XwDa8o1RMLT+2hAsigtTvbIGVqhX46szUifBGswUeCPgAGB7QeLk0X4Ork+HOxo1VgSqGASjMqkn8W4r4vVtEgI/RRQEL'.
'vaoGD85cl5V3nySR/S1mxWxab7f35PnntNyMJeRr9kCMqiHTy09EoeToLwggx6ymiMOD/VwcD7Oa/MHkcIiQx026WGYto5P/U+ZZ'.
'7gD0QwDuT5z9N3LrVPi0Xs543eQPKkRzaS54eviJIp4tMFQFMllAWN2qcRZHBnixNM8NYD162xq8u7ePSQ+GX2Pjwxc2dB2cLtB8'.
'7GgamCb0anBYBeChMtl8855CarclxU1gvViiUK4w2OMkNDnGeJ8bt9fH90yOnOkCwLFTwhzykhvtYzOWoBBbY//R3dbaNTYhf2RO'.
'QpeuUMzv188MlwuHy0H13HnE48UzMcL0WAtUHX8OxZHoG1URiFw7rnLLCswuSPD1ulze/iWjT2PSf+dBXRFtVVGIvzqph0pQL7VE'.
'avXYaXXxPwsnt0imdttCocMmZBdK7YU9D8wuNOW0nXc6QWzPsSa5naZ1beb9BbGB6dxGtMnXAAAAAElFTkSuQmCC' ;
 
//==========================================================
// mail.png
//==========================================================
$this->iBuiltinIcon[3][0]= 1122 ;
$this->iBuiltinIcon[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'.
'AAALEAAACxABrSO9dQAAAAd0SU1FB9AJHAMfFvL9OU8AAAPfSURBVHictZRdaBRXFMd/987H7tbNx8aYtGCrEexDsOBDaKHFxirb'.
'h0qhsiY0ykppKq1osI99C4H2WSiFFMHWUhXBrjRi0uCmtSEUGgP1QWqhWjGkoW7M1kTX3WRn5p4+TJJNGolQ6IXDnDtz+N0z/3PP'.
'UWBIpdpYa23b9g09PZ2kUrOrvmUyGVKp1Ao/mUyi56YnVgWfO/P1CihAd/dJMpmaNROIRq8BkM1m0bH6TasC3j6QXgFdXI+DR6PR'.
'JX/Pno8B+KLnMKqlpUU8z8MYs2RBEDzWf9J+0RcRbMdxGBsbw/fmCXwPMUEYID4iAVp8wIRmDIHMo4yHSIBSASKC+CWE0C/PF9jU'.
'3B6Cp+4M07C5FUtKGNvGwQJctPgIsgD2wRhEIqAMGB+UQYkHJgYYZD7P1HwVlmWhHcfhyk83KeRGUW4t6CgoG5SNUS4KBWgQDUov'.
'7AGlwYASBVqH0Bk49dXpCviVV3dw/tI1Bvr7kMIIlh0NYUpjlF0BAYvcxSXmEVLKceHSCJm+PnbueBHbtkNwTXUNBzo6aGpq4sSZ'.
'GwT5H7BsF6Wdf1GWHQAoM0upeI9PT1yioS7B7tdaSdSuw7KsUGMAy7HYsmUztTW1nMwM0txssX1rlHjjS5jy/Uq2YkK/eJuLl6/z'.
'x+1xkslW6mrixGIODx8EFSlEBC0+tmXT0NhA2763iEUjnLv4C8XpUbSbAB1mKkGJ3J83Od77HW5EszvZSqK2iljMIeJaRGNuJePF'.
'6mspY7BJ1DXwQnCd2fxGRq5OUCz8xt72dyhMZcn++Cu3xu9SKhdp2b4ZHWnAtTSxmIWlhcIjlksR3lNBYzlxZsb7+f7ne+xtSzOd'.
'u83szH1OnThOPp/n+a0beeP1l4mvq+PU2Qyd+5PY1RuwlAqLYFaBfbTbyPSdfgaH77A//QF4f1O/vpr6RJyq+C5Kc/M8FbFxXItY'.
'xOHDrvfo/fxLDnbsJBp5BowBReVWYAzabeTh5ABDw7cWoNNL3YYYNtSv57lnn6Z+Qx01VeuIuBa2DV1HD3H63BAPZu4u1WGpeLHq'.
'Rh7+NcjA0O+0p4+CNwXigwnbWlQQdpuEpli+n+PIkcOc//YKuckJJFh2K2anrjFw+QZt6S6kPImIF/b+cqAJD1LihWAxC61twBTo'.
'fPcQF/oGsVW5ovHQlavs2/8+uYnRVSOUgHAmmAClBIOBwKC0gPjhIRgEIX2wg7NnwpZW3d3d4vs+vu8TBMGK51rvPM9b8hdteZxd'.
'LBbVR8feJDs0Rlv6GFKeXJ21rNRXESxMPR+CBUl0nN7PjtO+dye7Up/8v1I88bf/ixT/AO1/hZsqW+C6AAAAAElFTkSuQmCC' ;
 
//==========================================================
// startconstrain.png
//==========================================================
$this->iBuiltinIcon[4][0]= 725 ;
$this->iBuiltinIcon[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'.
'AAALDgAACw4BQL7hQQAAAAd0SU1FB9ALEREICJp5fBkAAAJSSURBVHic3dS9a1NRGMfx77kxtS+xqS9FG6p1ER3qVJpBQUUc3CRU'.
'BwURVLB1EAuKIP0THJQiiNRJBK3iJl18AyeltRZa0bbaJMbUNmlNSm5e7s25j0NqpSSmyag/OMM9POdzDuflwn8djz8gClVRrVEV'.
'ur4Bl1FTNSzLrSS6vbml0jUUwSXj8Qfk3PkLtLW2AeBIybmrgz3+gFzpucjlE4f4btuFTuWuCF5XDr3a3UPf6cM8GQvxzbsRAJdh'.
'ScfxSywml5j7mVypN0eGEJ0tebIre+zxB6Tv7jPReS2hREpOvpmUXU+H5eC913JnNCSRVE60pUVbWoZjprR39Yq70bdqj4pW7PEH'.
'5FpvL9e79jOTTHM7ssDL6CJZ08LbvAGnrpZg2mI2Z/MlZfN8IkxuSwu4V9+WIrj7zFlOHfXzKrLIi2SGh5ECKjnNVNxkQEc55vOw'.
'rb6O8JLFdHyJ+ayFElUeHvjwkfteL/V7fKTSkFvIQE4DoLI2Mz/muTkTApcBKIwaN8pwIUrKw+ajWwDknAO0d/r4zFaMuRS63sWm'.
'RoOdm+vRIriUYjKexrQV+t1o0YEVwfZSVJmD/dIABJuO0LG3lRFx0GOfiAELE9OgCrfU0XnIp5FwGLEy5WEAOxlR5uN+ARhP7GN3'.
'5w7Gv4bQI2+xpt4jjv2nWBmIlcExE2vDAHYioszBZXw6CPE4ADoWVHmd/tuwlZR9eXYyoszBfpiNQqaAOU5+TXRN+DeeenADPT9b'.
'EVgKVsutKPl0TGWGhwofoquaoKK4apsq/tH/e/kFwBMXLgAEKK4AAAAASUVORK5CYII=' ;
 
//==========================================================
// calc.png
//==========================================================
$this->iBuiltinIcon[5][0]= 589 ;
$this->iBuiltinIcon[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAA4AIwBbgMF12wAAAAlwSFlz'.
'AAALEQAACxEBf2RfkQAAAAd0SU1FB9AHBxQeFsqn0wQAAAHKSURBVHicnZWff+RAGIef3U/gcOEgUAgUCgcLhYXCwsHBQeGgUDgs'.
'FgMHB4VA/4Bg4XChWFgIFIqBwkJhsRAYeOGF+TQHmWSTTbKd9pU37/x45jvfTDITXEynAbdWKVQB0NazcVm0alcL4rJaRVzm+w/e'.
'3iwAkzbYRcnnYgI04GCvsxxSPabYaEdt2Ra6D0atcvvvDmyrMWBX1zPq2ircP/Tk98DiJtjV/fim6ziOCL6dDHZNhxQ3arIMsox4'.
'vejleL2Ay9+jaw6A+4OSICG2cacGKhsGxg+CxeqAQS0Y7BYJvowq7iGMOhXHEfzpvpQkA9bLKgOgWKt+4Lo1mM9hs9m17QNsJ70P'.
'Fjc/O52joogoX8MZKiBiAFxd9Z1vcj9wfSpUlDRNMcYQxzFpmnJ0FPH8nDe1MQaWSz9woQpWSZKEojDkeaWoKAyr1tlu+s48wfVx'.
'u7n5i7jthmGIiEGcT+36PP+gFeJrxWLhb0UA/lb4ggGs1T0rZs0zwM/ZjNfilcIY5tutPxgOW3F6dUX464LrKILLiw+A7WErrl+2'.
'rABG1EL/BilZP8DjU2uR4U+2E49P1Z8QJmNXUzl24A9GBT0IruCfi86d9x+D12RGzt+pNAAAAABJRU5ErkJggg==' ;
 
//==========================================================
// mag.png
//==========================================================
$this->iBuiltinIcon[6][0]= 1415 ;
$this->iBuiltinIcon[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'.
'AAALDAAACwwBP0AiyAAAAAd0SU1FB9ALDxEWDY6Ul+UAAAUESURBVHicdZVrbFRFGIafsyyF0nalV1R6WiggaAptlzsr1OgEogmC'.
'0IgoBAsBgkIrBAPEhBj/AP6xRTCUFEwRI4jcgsitXMrFCJptJWvBNpXYbbXtbtttt6e7e86ec/yxadlCfZPJZDIz73zzzjfvR2VL'.
'F7U+hf0HD2JduIzTFy6SlJRkPtkcDgdCCE65OxFC8NPV6wghyM7OptankJ2dzbSC5QghEEIgCSHog9PpNAF27dlN6miZuPgElB4/'.
'nmY3O7ZtByA1NVUCkGWZweD1eklJScESTbqxuIjrd+/x6uIl5M19hSy7nfGOeUxf+g7VjU1sKi7C4/GYsiyz7tAJAD4/cRaA1tZW'.
'AHIPnECUVGD1+/3U19ebG4uLeHf1akamjsIwoVnVCOvQEdLoVILYYmMo3PIxSBJflpSaDX5FAmju1QAYv/8k/s8+wLVxOU0jR2LZ'.
'8sMFAApWrCApbRRDrRZirBYSLBKaoRPQw3SFernf2sav7T0Ubt4KwL4FMwF4Vu8FoHBCKgCzDhwHwLIhZ7y5a89u4m2JhA0wTdDC'.
'OrphEjJMNElCHxKDEjaobmvlfo/Krj27CQQCJsCGJW8C0KXqAMxMiosQA8hZWcTFx9OsaniDKh1qmG7VoFsL0x0K06kbeAMhWpRe'.
'/KpG+gwHAKUnz7Dz3BUMw6DK18nuw99wt0Nh6VdHI8RJicmETQgFg7SFwjSrGv+oKp6ghldV6dZ0ugJBlF6FmCESQ2w2AIqXLsan'.
'BrFYLJTnTCBrdBqveeopWZiPFaBHUegJhegMqGgxEkHDwB/UaQ9rdIV06v0+TD2EEQjQFtAY0dsNgNvt5sialQAIIXh7wQKuVf6J'.
'gTsSccPDWlQstClBGjr9eHpVWvUQncEwdYEedF8noQ4vmYmpZMTH0nTvDn25vLbrNmu7bvfnsYEbAMnhcPDgwQPzUo2LJusw/mhp'.
'QwlHNO0KBAnoIfxtrcQMT2De1Mm891wyUzNlUlJSpIyMDBobGzlzr5rFM/Koq6vrP8ASGxsLwPmKcvIShjPGZiPOakE3VFB8hHwd'.
'vJAxhrk5L7Ly+RQuH/sWgPdXrwFg/6HDFBUsIj09nehfbAWwPWOT9n5RYhqGwarNWxkRM5TRCfF4U1PQsDDJFk9uYhwXvzvKjm3b'.
'KSsro3DJInNW5RXp7u2bAKSlpeH1esnPz6eqqgqLpmmcr3Fht9ulfaV7mZk1Bs+lM6T1djM9fhg5egDPpTNMy5TZsW07kydPYdWM'.
'aXx96ixOp9O8cfUa80srmDpjOgAulytiQqZpMnvObLbt/JTtHxXj9/tRVdU0DGOAufRpevPDTeac0hJyc3NxOOawfv161lVWS6eX'.
'z+9/UOCxu1VWVvaTRGv16NFfjB2bNeAQp9NpTpmSM4DcbrdL0WsGDKLRR+52uwe1yP8jb2lpYfikyY9t80n03UCWZeaXVjw1f+zs'.
'Oen+/d+pqanhzp2fKSsrw+l0mi6XiyPl5ZGITdN8fAVJwjRNJEmi1qfw1kw7siyTnJxMe3s71dXV3GpoZO64DG41NPJylvxU5D/e'.
'qJKsfWQD9IkaZ2RmUvr9aV4aGYcQgjfO3aWoYBF5eXm4ewIsu/CbdPz1aWb0/p1bNoOrQxlUiuiaFo3c3FyEEOx9+C9CCD6paaTW'.
'p/TXyYkTJ0Xe59jf7QOyAKDWp/QXxcFQ61P4pT3ShBBcvnUHIQTjxmX19/8BCeVg+/GPpskAAAAASUVORK5CYII=' ;
 
//==========================================================
// lock.png
//==========================================================
$this->iBuiltinIcon[7][0]= 963 ;
$this->iBuiltinIcon[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'.
'AAALCwAACwsBbQSEtwAAAAd0SU1FB9AKAw0XDmwMOwIAAANASURBVHic7ZXfS1t3GMY/3+PprI7aisvo2YU6h6ATA8JW4rrlsF4U'.
'qiAsF9mhl0N2cYTRy9G/wptAYWPD9iJtRy5asDe7cYFmyjaXOLaMImOrmkRrjL9yTmIS3120JybWQgfb3R74wuc8Lzw858vLOUpE'.
'OK6pqSm2trbY39+nu7tbPHYch7m5OcLhMIA67kWj0aMQEWk6tm17rNm2LSIie3t7ksvlJJ1OSyqVkls3Z8SyLMnlcqTTaVKpFLdu'.
'zmBZVj1HeY2VUti2TSQSQSml2bZdi0QirK2tMT09zerqKtlslqGhISYnJ4nHv2N+foFsNquOe9FotLlxOBwmk8lgWRbhcFgymYxY'.
'liUi0mqaJoAuIi2macrdO7fFsizx3to0Te7euV1vrXtXEgqFmJmZYWVlhXK5LB4/U9kwDL784kYV0A3DYHd3m4sXRymXywKoRi8U'.
'Ch01DgQCJBIJLMsiEAhIIpHw2uLz+eqtYrEYIqKZpimxWEyCwaCMjY01zYPBIJpXqVQqsby8TLVabWKA/v5+RkZGMAyDrq4ulFKH'.
'HsfjcWZnZ+ns7KTRqwcnk0mKxSKFQqGJlVKtruuSTCYB6O3trW9UI/v9/iZPB/j8s2HOnX0FgHfeXpeffnzK+fWf+fijvhLs0PtG'.
'D/n1OJ9+MsrlSwb3733DwMCAt1EyPj6uACYmJp56168NU6nUqFSE9nZdPE7+WqC/r4NKTagcCJVqDaUUB5VDAA4Pa9x7sMLlSwan'.
'WjRmv13D7/erpaWlo604qOp88OF7LC48rPNosMq5Th+Dgxd4/XyA1rbzADi7j8jnf2P++wdcvSr8MJ/i8eomAKlUqn41OsDAQDeD'.
'g++yuPCwzm/2vU8+n2a7sMFfj79mp7BBuVzioFSiXHJx3SKuW2Rzy0Up9dxnQVvODALQerqNRn4ZKe0Mvtc6TpzpmqbxalcY9Ato'.
'2v06t515C73YQftZB9GLnDrt4LoujuPgOA4Ui+C6yOpXJwZrJ7r/gv4P/u+D9W7fLxTz+1ScQxrZ3atRLaVxdjbY2d184R6/sLHe'.
'opHP7/Do90Ua+WWUyezzZHObP/7cfX54/dowE1d66s8TV3oE+Mfn+L/zb4XmHPjRG9YjAAAAAElFTkSuQmCC' ;
 
//==========================================================
// stop.png
//==========================================================
$this->iBuiltinIcon[8][0]= 889 ;
$this->iBuiltinIcon[8][1]=
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'.
'AAALDwAACw8BkvkDpQAAAAd0SU1FB9AJDwEvNyD6M/0AAAL2SURBVHic1ZTLaxVnGIefb2bO5OScHJN4oWrFNqcUJYoUEgU3/Qf6'.
'F7gwCkIrvdBLUtqqiLhSg9bgBduFSHZdiG5ctkJ3xRDbUFwUmghNzBDanPGMkzOX79LFJGPMOSd204U/+Bbzvd/78F4H/ieJdoad'.
'pZKxRFszAI/DcP0HazXY22v+HB01kee1PA/v3zfnjx4xgGnHcNZe7OvuNj+cOEF1ZATv5nUA4jhBSgmADCVWo8Ge2Of9wb18P/G7'.
'oUXmYi30zqlTVEdGWLh1g2D6MYlKkXGE0Vl8aa2GEB149+4xXSzyoOIw/mimiZV/DPb25pFOj13A9gOMEChhUEqhVYqWKUk9QAUp'.
'sT/P4s8PmKlUmNhQaIJbkDVqBbpw6wZ2zUc4Nm+ePku5p4eOrgpueQOFUoVCVxcD4+N07dpF9+5tVJeWGPBjhvr7WF1zC8ASgtcP'.
'H8a7eZ1odh4sh50nzwCw9ZNh3M4Stutiu0X2nB/LyjZ6lcIbVTpdQU/jWVPzLADM8+ZGBRdtC7wrF/O7bR99iu26VL86iU4SAH4b'.
'Po5d6AQhstMSvGyI4wS5FJBKSRwnzF8byx/u+PjzzMF1mfryQ1K/jnCahqp1xEopjFLoNEFJSRJHzF799gWHqa+/QKcSUXBI609f'.
'Al5W4teQSiHDOipNUKnMI13RvnOXAIEKQixvGWya98SC560MFwPiqEG86JM8q79Q06lvhnOndy5/B6GPCUOMUu3BQgg8z0M3GmBZ'.
'iGJn3v2VmsqnfzNx7FDueODuj8ROCFpjtG5TCmOYv32bJ09msP0ISydMfnAUgF8/O45RAA6WTPjlvXcB+Gn7FuRf/zAnNX6x3ARe'.
'PSdmqL+P/YHkwMGDOGWDZTlQcNBRhPEComgB/YeHfq2InF1kLlXUOkpMbio1bd7aATRD/X0M1lPeSlM2vt2X1XBZjZnpLG2tmZO6'.
'LbQVOIcP+HG2UauH3xgwBqOz9Cc3l1tC24Fz+MvUDroeGNb5if9H/1dM/wLPCYMw9fryKgAAAABJRU5ErkJggg==' ;
 
//==========================================================
// error.png
//==========================================================
$this->iBuiltinIcon[9][0]= 541 ;
$this->iBuiltinIcon[9][1]=
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaVBMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'.
'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpYiYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'.
'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTCAkUMSj9wWSOAAABLUlEQVR4'.
'2s2U3ZKCMAxGjfzJanFAXFkUle/9H9JUKA1gKTN7Yy6YMjl+kNPK5rlZVSuxf1ZRnlZxFYAm93NnIKvR+MEHUgqBXx93wZGIUrSe'.
'h+ctEgbpiMo3iQ4kioHCGxir/ZYUbr7AgPXs9bX0BCYM8vN/cPe8oQYzom3tVsSBMVHEoOJ5dm5F1RsIe9CtqGgRacCAkUvRtevT'.
'e2pd6vOWF+gCuc/brcuhyARakBU9FgK5bUBWdHEH8tHpDsZnRTZQGzdLVvQ3CzyYZiTAmSIODEwzFCAdJopuvbpeZDisJ4pKEcjD'.
'ijWPJhU1MjCo9dkYfiUVjQNTDKY6CVbR6A0niUSZjRwFanR0l9i/TyvGnFdqwStq5axMfDbyBksld/FUumvxS/Bd9VyJvQDWiiMx'.
'iOsCHgAAAABJRU5ErkJggg==' ;
 
//==========================================================
// openfolder.png
//==========================================================
$this->iBuiltinIcon[10][0]= 2040 ;
$this->iBuiltinIcon[10][1]=
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEANAAtwClFht71AAAAAlwSFlz'.
'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDQ4RIXMeaLcAAAd1SURBVHicxZd7jBXVHcc/58zcvTNzH8vusqw8FsTsKiCUUh5WBZXG'.
'GkOptmqwNWsWLKXFGlEpzZI0AWNKSy0WhDS22gJKtWlTsSRqzYIuLGB2WVvDIwQMZQMsy2OFfdzde+/OnHP6x907vJaFpjb9JZM5'.
'c85Mfp/f9/s7Jxn4P4e41gtSyp78WGvtfdEAcqDFYUOH9HS0NhGk9tPb/ilSyp789UUB2AMuqhQy3Uzm7HGkE6W3dTNZMRI3EcWO'.
'jf9ClLmWBT3dzW8jUsevWHCG3UpWl+IkHSxnbDh/Mcz12NevBcuWXTmf6TjnXvJ88gDmVB3pw3+nt3UzHa1NqMzBS2zqPLGFjtMN'.
'ZNr3XdW+qyqwZcFk76HX/tHWfuQvyO4W7qhaHwL8efkMRlRUpPv7rqD0RrJ+FgAjLy1a20OIxZJEEuNCRfIApj+om4bGM3u2/sYU'.
'9J41d8973f3Dhg1pISTV1dXXBRNJxPGFCzhou+DCQrScZOkktNaeDZjamgeZ9MgiYmVDccvHhjAzJw0NTh8/alyZMaVJicp0iTHj'.
'JpgNv38tjWUhhGROdbUL9W5/MH5XCkjlcibi+KIop5LVHLKEu8A/f4r286doa9pGrGwYAAsfqbbH3b8MgO/Nqgy6WvdbbXHMkEFJ'.
'4xUOMVEvaTZu3BgmvF4Yk4hz9rO/Ulr5cE9owae/rcGxohSOuiWkC2IjcIqKyPZm+OmCH7GhoZEF077EEzVVweAbJ+riEeO0Ey8y'.
'UubqOHn0AOgMwvf59txnBrSp9dgxKmf/+kIP1NY8SFk0jh5ajmNHAWg5b2E5EexojGHjbiVRMoRMNs0LC+Yz46vTuH3enN7BI8fr'.
'qFdo0BoVZNC9aVSQ4fNjBzEmQJiARxb+/AqYPMAVB5FsPU5v37g9OxgLhe14ZM5/ju052E6MNZvf5pmHHuLmmWOkEysxUtpGAtme'.
'dtHTflJkezqQto3jFRnLssyf1jydxiiM7zNnye/c3ZsqLu2BN5fcMfzrv/hby1tPzmRUoihcTJ87CwQI2yLtDcIqsIjYUf51qBlf'.
'OnScOSrdQUOMURkiXsLUzJnvbGhoBGDHH5cGyZLhOpYoNl5hqYnYEXOu5fDl9eYAHntx98n8hFHZcPHUuTSxSASAeK/CGIOxJJ0f'.
'bOGNPU280dgkq6Y2yu8vfjCIlwwzr+/ZQ/PHO0gOLuO5qsftDQ2NbN+4OCgqG6WTxWVaq6zpF+DiSHWnicdylp3r6aZTWthIOrNp'.
'ktHcvBu0sHX1Sm6ozB3B42d90zZA9bQp7PvgPSzXZfnqX/HS4DKKK2+x69Y/HURs26iBAN5ccsfw7774UcumF37C6f07KSt2OHji'.
'DEUJD0tISjyPrrSPlAKvN0JP/U4O1NfjuhG2rvklN1SOpfXwftpbTqAyKRrff5fb7rs9V1R7m4wlz2ihA3HpmXflUWyOH2umpLiY'.
'ui3v8M+6bWzfsRNbSgqkxaCkiy0simMuEWEhpcRzIhQWOIAh6tiAwS4owInFiTou5dOnMnl2NR++ujBwXEc9terD6M43nrj6LgAB'.
'QnDPA9/irtkP8JRS7Hr/3T6YekDQ1pEiEXOwpUVJzCVlZZFS4mZtkpEo9ChAkDp/jtLMBACy6S4RiQghLyv5cgBRPnKUOX6smUGF'.
'hSil0MYw9d77mPy1e5mnFE3batm3czvb6nYgEJztSFGU9LCRlMRdUjIH0+lnEMIwPNXD3NumoVJnrMCJaiciMUZfvQnz4QcBSvV1'.
'vjE5GK358t0zmXDnDB79saLpo20c+aSRD+t25JTp7GZQwsEWFiVxl6hlUf/WO9z32CxmL1rOe6u/I2KuwGhzLQCB7/sYY9Bah3el'.
'FKbvrrVm4vS7GH/7ncx+chEHGz7myCeNbPtoO0JI2jq78WIRLGkzsqs7V5SfFV5EovXACoiqqsfNpk2vo5VCWtYFBfoU0VoTBAFa'.
'a7TRaK2p+MoURk+cxMzq+Rzbv49DDbuo27UTW9h0dedssPxuK+kIfN8XxhgDYPVXf2Fh4XKtFIl4AiklAlBKAYRKKK36wHIweTCt'.
'NfHiEkaOn8j0+7/BmDFjaT30GbHywSxcuZkpFfFg+m1jjZ/NmnVvNfRvwd69e8WBA/uNFAIh4JVXXmHsmDHE4vEQQgjQ2lxQIm9N'.
'nz35q3BEOZOHzaG2thaA4mRU+L29It+IV21CpbRQfeMFC35gRB/M2rVrubnyZmLxWJhECBEmz/eHyo/7lMlH3LFFujsthNFCCGOu'.
'+WNyeUgpjSVzMKtWraKyshLPdcPEeYWCIEBdpIxSivr6eta8vI7d6+cGnhdV06pe1QP+F/QXWmuRL+jZZ58LlVmxYgUVFRV4rhtu'.
'4TzMxXAA6XRaRAtsYUkx8I/JtSJQOlSwpmZpCLN8+fPcdNNoHMfB9/0QJgRoP295TlR7UVv8xxZcHMuWIZ9/Hn35vG3JEGZpzVJG'.
'jx5N1IlitKahsZE1L69j69qHgx+urFX/lQL9JYdLlfnZihUhzOLFi8N3Ml1dthOxVH/f/8/CtqSJ2JaJ2JZ59J7RPsC/AViJsQS/'.
'dBntAAAAAElFTkSuQmCC' ;
 
//==========================================================
// folder.png
//==========================================================
$this->iBuiltinIcon[11][0]= 1824 ;
$this->iBuiltinIcon[11][1]=
'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'.
'AAALEAAACxABrSO9dQAAAAd0SU1FB9ECAQgFFyd9cRUAAAadSURBVHiczdhvbBP3Hcfx9/2xfefEOA5JoCNNnIT8AdtZmYBETJsI'.
'6+jQOlQihT1AYgytqzZpD1atfyYqlT1h0lRpT7aRJ4NQpRvZGELVuo5Ua9jEJDIETQsNQyPBsUJMWGPnj//e+e72wNg4xElMR6ed'.
'ZNln3933dZ/f93f6yfB/sgmrHdDV1WXlPg8NDZUDScD8LFFFEZZlWYZhWMFg0Orq6sq/gDJAfFy1iiZy9OjrVnj4JzQ1rMWqfxm/'.
'309jYyNtbW0kEgnu3bvH4cOH88c/jqSKQl4/XGkd+eVtAN46up1LH92ktqYS++ZX8Pv9NDQ0sGnTJlKpFOFwmO7u7vy5IyMjeVRd'.
'XV1+WEOh0IrY4pDnq6wXX/sTiCJaMkFZdRNqxefoe7VtCSqXVDqdZnZ2ltraWkzTpKqqijt3JpFlG7dvj7NzZ1f++qFQyA3EClHL'.
'Ql743nFkhxPDtJAd5eTaYSVUfX09lZWVlJWVIUnSg7sVQMBCUcu4ceMGe/bsIRQK1QAzOcyykIM9P0KyudAyCWyqG8nhwqa4SkLt'.
'3r0bVVVxu924XC40TUOWZUQxe97CwgIdHR2LMHIxSCaVInVvFElxE0vMY1Pd2NUKJMWNTXHlUfF//4vETJCelwbpFm3MjP2dt37x'.
'AlN+PzU1NViWRSwW4+7du3g8HjweD4qi5EFAJzAExIpCANbooxhplfB0FJvTg6xWIqsVRVF6MopkU3FXPcnkJxGU0VEAdF2noqKC'.
'W3/8DpnqLjzep2lubsblcjE8PExHR8fboVDID9xYFpLBDpJF0jDQIncQpWlkm31FlFLtp9PfyuW/vYQj1kPSuRW/38+lj27S2Q7v'.
'/aWXUBVUffVNtm3blivVCEwsC5Eyc5iiApEpDEAXMqQdldhSiWVQHjJagud+8Fuexck/zv+K82dfoSbSCsDe75/km+4GVPd6+l5t'.
'4zJHcqVUYN2yEEtZQDCSJCueRAYsPY49HsFIZVG6p25JUumFafT4DKJN4amtT7Nz38sk5+5A70HMtEYyMkFiZhxzjQ/poXrLQrRU'.
'DFGEeFpAlkQkm4pRiCpIKodKzk0T/2QMh+piPjxKZPwiSkUtu/b9mNnJEWS7E8nhAmvpM60oJDkXJxqNozxRRUxPIesispBBlsXV'.
'UaKEFo8gzoaJhz8s2lOmrpUG+WBhJ9/60g+Z+fDXTAXfxllRjl1VkO0OFATsYhYliiK21ZKKhhHnFveUqSdKgwAEOp7F2v51vvw8'.
'XH7/N1wd/BlTweuUV65BdtgfoLTSkipsdD3tRi0VYpommUwGwzDwdT5HYEc3giAwcvH3jLz3BlPB67jWeZBEKYsSBWwpHZtNKo4q'.
'aHTDsJeeiGEYWJaFZVmYpommaRiGQdPnv0bb1m8gSRL/vPIOV979aR4lmAJ2p4qCgCxksNuKJ6VNpx4NYhgGpmkuQhmGQTqdxjAM'.
'qr2d7HtxEEEQuH1tkKvvvkF44tqDnrIcKJKAPf1g+LAUElq8dIiu60sApmnm93Pfzc7OYhgGrie+wFe++ztcLhcT1wf54PzPCU9c'.
'w7XWjWS3IdsdOAUBWZAxrRJnTQ6SG5bce2FCpmkughmGQSqVYm5uDtnj44sH38TtdhP6+Dwf//V4ttHXrkGURZJaic8RgHQ6jWma'.
'SJKUL5RLKNfIOczDKF3XSSaTRCIRhLJWntp3nGfWrSMxc5OLf3iNP4+68T9Ub9nF76lTpxgfHycajZJKpdA0LZ9GbjYV7hcDWZaF'.
'pmnMz88Ti8UYunSLmu1HFi2aVkxkaGjINTY2ttDb24vX6+XQoUNs3ryZ8vJyIDu1BUFYkkxhgxeiWlpaOHPmDE1NTdTX1xe98eWG'.
'JnF/9dQZCoXUYDA4AOD1ejlw4ACtra2Ul5fniwmCkEcUJiUIAoFAgL6+Pnw+H21tbfT39z8SxCS7hHsfWH9/8dL4MKqnp4eWlhac'.
'TmcekEvMNE2am5s5ceIEgUCA9vZ2Tp48ic/nY3j4UsmQHCYOjJHtpeBKqL1799Lc3IzT6UTXdRobGxkYGKC9vZ3W1tZ8Ko86NJ8a'.
'tXHjRo4dO8bp06fZsmULGzZsoL+/n0AggNfr5ezZs/8VpGTU5OSkc//+/acBfD4f1dXV7Nq1i4aGBs6dO4fP5+Pq1SuPBbIiyjTN'.
'RUnV1dUNXLhwAa/Xy44dO4jFYgBEo9FFF1r134BPuYlk16LrAYXsAlmtq6sbKDwoFAp9m+ykuP5ZQVZF3f8tCdwCov8LyHIoAANI'.
'AXf/A1TI0XCDh7OWAAAAAElFTkSuQmCC' ;
 
//==========================================================
// file_important.png
//==========================================================
$this->iBuiltinIcon[12][0]= 1785 ;
$this->iBuiltinIcon[12][1]=
'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'.
'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ECDAcjDeD3lKsAAAZ2SURBVHicrZhPaFzHHcc/897s7lutJCsr2VHsOHWMk0MPbsBUrcnF'.
'OFRdSo6FNhdB6SGHlpDmYtJCDyoxyKe6EBxKQkt7KKL0T6ABo0NbciqigtC6PhWKI2NFqqxdSd7V2/dmftPDvPd212t55dCBYfbN'.
'zpvfZ77z+/1mdhUjytWrV93Hf/24eD5z9gwiMlDjOKbb7dLtdhER2u02u7u73Lp1CxEZBw4AeZwdNQqkMd9wbziFGINJUt6rRbz5'.
'1ptUq1XK5TJBEAAUMHt7e+zu7gKwvLzMysoKwAng/uNg9CgQgFKlgg1DUJ67Vqtx6tQpZmdniaIIpRTOOZRSdDoddnZ2aLfbLC8v'.
's7S0xJUrV7ZGwQSj1PhhfRodVdDlMrpc5vup5Z2fvMPdu3fZ29vDWjvwztjYGPV6nVqtRqVS4dKlSywtLQFsAdOH2XwsCEApg3jl'.
'w98Rak2gvYjNZpNms0mSJDjnHgkDMDc3dySYQ0Ea8w139YUX0OUKulzyg7UmCEO+l1huvHuDra0t9vf3h1TJYSqVypFhHquIrlQI'.
'S5qv/uIDAC7/4bcEQYAKvK+0Wq1DVQGIoog7d+4cCeaRII35hrt+8SsEOkRlUaEyR0UpFIrXHxyMVKVUKnHv3r0jwRwaNelBjBjL'.
'Sz/7KYuLiwAsLi7y4z/9kY9e+TpkCuSqjI+Po7XuAWeKXLt2DWNMUZMkwRjDhQsXWFtbK6JpCCT3jfQgxomPtPX19YHWicM5x3c2'.
'73Pj3Ru8/aO3mZqaolKpoHVvyuvXr/Ppnf/Q7uzz380NPtu4y/qnG+ztd1hfX2dtbQ3gIvDnRyqSxl1UoPjyz98D4PTp0wPtq39Z'.
'4fdzLxegrVaLVqvF5OQkYRgWqpRKJZ77wvNsbW1RG5tgfKLOTH2G7Z1twqBQrgrMDvhInjfSOCY5iIv+hYWFgRZArEWsZWF941Bf'.
'SdMUgMnJCWpjVU4cn+HUyePM1Gc4+fRUPkzBI5w1jbukcczLv/5l0XfmzJmBFuCba38r/CRXpT+CrDUoZ0jjB4RYonJAOYRobJKT'.
'z5zgqfqxAbsFSH6mpHFM2qdGXh4VnoViD6mSJF2cTQeqDqBaKVHWmonJCWpZjhkC6anR5WsffTgwaHV1FaUUq6urA/2v3f5k4LnV'.
'arG9tUn3oI2YBCcWHYAxMVYs1qZEZY2SFB2aYZDGfMN9d7uJiWPSeFiNo5Rclc3NTXZbO6RpF7EJVixYA9agwwDnUiqlEPdQ3imi'.
'Jo27BGHIt/7x9yEjc3Nzh27Na7c/4TdffKl4bja3ae5MUIu0T/HOEIaOpJt4gwoSsVTK4SBIY77hFtY3ABBjBiZ90rKwvsH77/+K'.
't37wOhO1iPpTk4SBw1mLsz6CnKQ4l3qV+kE+t9XHlNZOk+bUJLVIE1VCcIJWQmJ6qjj30NbcXLkZMt8YPig+Z3n1G5fZ39/j/vY2'.
'9ckqZT2Ochbn0p4qNkU/dDfUADdXbh4HXgRO4zNdEU0XL1784PLly5w9e7Z4SazFOfGrEotDcOKrcoJPmrYIXf/Zop3QNd1skuGt'.
'cUAb2MgAxvHZTgFUq1Wmp6eZnZ0F8JlTjDduDThBnDeECEoJtbGIp6enqEblzCcEZ1PECU4yVRiOGgd0gc+AB0CZvkv1sWPHOHfu'.
'HOfPn8da41cpkkltEBEPJhYnBkTQJcdYVKGkgRxCfBsq5xXNgAa2Bn+hjTOgHEKBP8pzRUxykIH4ifLJRTJAl+UMBJzPHQ6bfe/f'.
'cWIzPxlUpD+zugzIZtVk1d8znBAqRxgoQuVQgSJQ3h9C5QhDRYgjUILCAzlnEdsHYTKfMTEBcP7F54YUGVmc2GLlIn6ve6v0ahSt'.
'8X25TzjJ+rIx1grKpQPWR4LkGVVsMgghvS0qjPdvm5OeceOTWA5Evo2mFzkjQfL7hZPUy5yvvF/uPFQL3+nbDmsLCEmT3sTmCTNr'.
'rogT6yFsOix3ftw7OwQhkvSU6CuinhCk0+kAkFoBazEEICHaHHiPVmU0gnUp4EAc1mYrF0EBVpwPi34VrBkwPxKk3W5ju/e5/c+d'.
'bGUHIAIuydTIE5zfc5Wr4lJcahHnHTP3CVGm78DrgY38N+DEibp7dmYKdAQmBh1hjEFjis+9CTWYGK21H6PxPyOI0DobYwzZF/z7'.
'7jadTvJtYG0kCD7lfwl49ijgT1gc0AH+dZSJA/xB+Mz/GSIvFoj/B7H1mAd8CO/zAAAAAElFTkSuQmCC' ;
 
$this->iLen = count($this->iBuiltinIcon);
}
}
 
//===================================================
// Global cache for builtin images
//===================================================
$_gPredefIcons = new PredefIcons();
 
//===================================================
// CLASS IconImage
// Description: Holds properties for an icon image
//===================================================
class IconImage {
var $iGDImage=null;
var $iWidth,$iHeight;
var $ixalign='left',$iyalign='center';
var $iScale=1.0;
 
function IconImage($aIcon,$aScale=1) {
GLOBAL $_gPredefIcons ;
if( is_string($aIcon) ) {
$this->iGDImage = Graph::LoadBkgImage('',$aIcon);
}
elseif( is_integer($aIcon) ) {
// Builtin image
$this->iGDImage = $_gPredefIcons->GetImg($aIcon);
}
else {
JpGraphError::RaiseL(6011);
//('Argument to IconImage must be string or integer');
}
$this->iScale = $aScale;
$this->iWidth = Image::GetWidth($this->iGDImage);
$this->iHeight = Image::GetHeight($this->iGDImage);
}
 
function GetWidth() {
return round($this->iScale*$this->iWidth);
}
 
function GetHeight() {
return round($this->iScale*$this->iHeight);
}
 
function SetAlign($aX='left',$aY='center') {
 
$this->ixalign = $aX;
$this->iyalign = $aY;
 
}
 
function Stroke(&$aImg,$x,$y) {
 
if( $this->ixalign == 'right' ) {
$x -= $this->iWidth;
}
elseif( $this->ixalign == 'center' ) {
$x -= round($this->iWidth/2*$this->iScale);
}
 
if( $this->iyalign == 'bottom' ) {
$y -= $this->iHeight;
}
elseif( $this->iyalign == 'center' ) {
$y -= round($this->iHeight/2*$this->iScale);
}
 
$aImg->Copy($this->iGDImage,
$x,$y,0,0,
round($this->iWidth*$this->iScale),round($this->iHeight*$this->iScale),
$this->iWidth,$this->iHeight);
}
}
 
 
//===================================================
// CLASS TextProperty
// Description: Holds properties for a text
//===================================================
class TextProperty {
var $iFFamily=FF_FONT1,$iFStyle=FS_NORMAL,$iFSize=10;
var $iColor="black";
var $iShow=true;
var $iText="";
var $iHAlign="left",$iVAlign="bottom";
var $csimtarget='',$csimwintarget='',$csimalt='';
//---------------
// CONSTRUCTOR
function TextProperty($aTxt='') {
$this->iText = $aTxt;
}
//---------------
// PUBLIC METHODS
function Set($aTxt) {
$this->iText = $aTxt;
}
 
function SetCSIMTarget($aTarget,$aAltText='',$aWinTarget='') {
if( is_string($aTarget) )
$aTarget = array($aTarget);
$this->csimtarget=$aTarget;
 
if( is_string($aWinTarget) )
$aWinTarget = array($aWinTarget);
$this->csimwintarget=$aWinTarget;
 
if( is_string($aAltText) )
$aAltText = array($aAltText);
$this->csimalt=$aAltText;
}
function SetCSIMAlt($aAltText) {
if( is_string($aAltText) )
$aAltText = array($aAltText);
$this->csimalt=$aAltText;
}
 
// Set text color
function SetColor($aColor) {
$this->iColor = $aColor;
}
function HasTabs() {
if( is_string($this->iText) ) {
return substr_count($this->iText,"\t") > 0;
}
elseif( is_array($this->iText) ) {
return false;
}
}
// Get number of tabs in string
function GetNbrTabs() {
if( is_string($this->iText) ) {
return substr_count($this->iText,"\t") ;
}
else{
return 0;
}
}
// Set alignment
function Align($aHAlign,$aVAlign="bottom") {
$this->iHAlign=$aHAlign;
$this->iVAlign=$aVAlign;
}
// Synonym
function SetAlign($aHAlign,$aVAlign="bottom") {
$this->iHAlign=$aHAlign;
$this->iVAlign=$aVAlign;
}
// Specify font
function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) {
$this->iFFamily = $aFFamily;
$this->iFStyle = $aFStyle;
$this->iFSize = $aFSize;
}
 
function IsColumns() {
return is_array($this->iText) ;
}
// Get width of text. If text contains several columns separated by
// tabs then return both the total width as well as an array with a
// width for each column.
function GetWidth(&$aImg,$aUseTabs=false,$aTabExtraMargin=1.1) {
$extra_margin=4;
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
if( is_string($this->iText) ) {
if( strlen($this->iText) == 0 ) return 0;
$tmp = split("\t",$this->iText);
if( count($tmp) <= 1 || !$aUseTabs ) {
$w = $aImg->GetTextWidth($this->iText);
return $w + 2*$extra_margin;
}
else {
$tot=0;
$n = count($tmp);
for($i=0; $i < $n; ++$i) {
$res[$i] = $aImg->GetTextWidth($tmp[$i]);
$tot += $res[$i]*$aTabExtraMargin;
}
return array(round($tot),$res);
}
}
elseif( is_object($this->iText) ) {
// A single icon
return $this->iText->GetWidth()+2*$extra_margin;
}
elseif( is_array($this->iText) ) {
// Must be an array of texts. In this case we return the sum of the
// length + a fixed margin of 4 pixels on each text string
$n = count($this->iText);
for( $i=0, $w=0; $i < $n; ++$i ) {
$tmp = $this->iText[$i];
if( is_string($tmp) ) {
$w += $aImg->GetTextWidth($tmp)+$extra_margin;
}
else {
if( is_object($tmp) === false ) {
JpGraphError::RaiseL(6012);
}
$w += $tmp->GetWidth()+$extra_margin;
}
}
return $w;
}
else {
JpGraphError::RaiseL(6012);
}
}
 
// for the case where we have multiple columns this function returns the width of each
// column individually. If there is no columns just return the width of the single
// column as an array of one
function GetColWidth(&$aImg,$aMargin=0) {
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
if( is_array($this->iText) ) {
$n = count($this->iText);
for( $i=0, $w=array(); $i < $n; ++$i ) {
$tmp = $this->iText[$i];
if( is_string($tmp) ) {
$w[$i] = $aImg->GetTextWidth($this->iText[$i])+$aMargin;
}
else {
if( is_object($tmp) === false ) {
JpGraphError::RaiseL(6012);
}
$w[$i] = $tmp->GetWidth()+$aMargin;
}
}
return $w;
}
else {
return array($this->GetWidth($aImg));
}
}
// Get total height of text
function GetHeight(&$aImg) {
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
return $aImg->GetFontHeight();
}
// Unhide/hide the text
function Show($aShow=true) {
$this->iShow=$aShow;
}
// Stroke text at (x,y) coordinates. If the text contains tabs then the
// x parameter should be an array of positions to be used for each successive
// tab mark. If no array is supplied then the tabs will be ignored.
function Stroke(&$aImg,$aX,$aY) {
if( $this->iShow ) {
$aImg->SetColor($this->iColor);
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
$aImg->SetTextAlign($this->iHAlign,$this->iVAlign);
if( $this->GetNbrTabs() <= 1 ) {
if( is_string($this->iText) ) {
// Get rid of any "\t" characters and stroke string
if( is_array($aX) ) $aX=$aX[0];
if( is_array($aY) ) $aY=$aY[0];
$aImg->StrokeText($aX,$aY,str_replace("\t"," ",$this->iText));
}
elseif( is_array($this->iText) && ($n = count($this->iText)) > 0 ) {
$ax = is_array($aX) ;
$ay = is_array($aY) ;
if( $ax && $ay ) {
// Nothing; both are already arrays
}
elseif( $ax ) {
$aY = array_fill(0,$n,$aY);
}
elseif( $ay ) {
$aX = array_fill(0,$n,$aX);
}
else {
$aX = array_fill(0,$n,$aX);
$aY = array_fill(0,$n,$aY);
}
$n = min($n, count($aX) ) ;
$n = min($n, count($aY) ) ;
for($i=0; $i < $n; ++$i ) {
$tmp = $this->iText[$i];
if( is_object($tmp) ) {
$tmp->Stroke($aImg,$aX[$i],$aY[$i]);
}
else
$aImg->StrokeText($aX[$i],$aY[$i],str_replace("\t"," ",$tmp));
}
}
}
else {
$tmp = split("\t",$this->iText);
$n = min(count($tmp),count($aX));
for($i=0; $i < $n; ++$i) {
$aImg->StrokeText($aX[$i],$aY,$tmp[$i]);
}
}
}
}
}
 
//===================================================
// CLASS HeaderProperty
// Description: Data encapsulating class to hold property
// for each type of the scale headers
//===================================================
class HeaderProperty {
var $iTitleVertMargin=3,$iFFamily=FF_FONT0,$iFStyle=FS_NORMAL,$iFSize=8;
var $iFrameColor="black",$iFrameWeight=1;
var $iShowLabels=true,$iShowGrid=true;
var $iBackgroundColor="white";
var $iWeekendBackgroundColor="lightgray",$iSundayTextColor="red"; // these are only used with day scale
var $iTextColor="black";
var $iLabelFormStr="%d";
var $grid,$iStyle=0;
var $iIntervall = 1;
 
//---------------
// CONSTRUCTOR
function HeaderProperty() {
$this->grid = new LineProperty();
}
 
//---------------
// PUBLIC METHODS
function Show($aShow=true) {
$this->iShowLabels = $aShow;
}
 
function SetIntervall($aInt) {
$this->iIntervall = $aInt;
}
 
function GetIntervall() {
return $this->iIntervall ;
}
function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) {
$this->iFFamily = $aFFamily;
$this->iFStyle = $aFStyle;
$this->iFSize = $aFSize;
}
 
function SetFontColor($aColor) {
$this->iTextColor = $aColor;
}
function GetFontHeight(&$aImg) {
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
return $aImg->GetFontHeight();
}
 
function GetFontWidth(&$aImg) {
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
return $aImg->GetFontWidth();
}
 
function GetStrWidth(&$aImg,$aStr) {
$aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize);
return $aImg->GetTextWidth($aStr);
}
function SetStyle($aStyle) {
$this->iStyle = $aStyle;
}
function SetBackgroundColor($aColor) {
$this->iBackgroundColor=$aColor;
}
 
function SetFrameWeight($aWeight) {
$this->iFrameWeight=$aWeight;
}
 
function SetFrameColor($aColor) {
$this->iFrameColor=$aColor;
}
// Only used by day scale
function SetWeekendColor($aColor) {
$this->iWeekendBackgroundColor=$aColor;
}
// Only used by day scale
function SetSundayFontColor($aColor) {
$this->iSundayTextColor=$aColor;
}
function SetTitleVertMargin($aMargin) {
$this->iTitleVertMargin=$aMargin;
}
function SetLabelFormatString($aStr) {
$this->iLabelFormStr=$aStr;
}
 
function SetFormatString($aStr) {
$this->SetLabelFormatString($aStr);
}
 
 
}
 
//===================================================
// CLASS GanttScale
// Description: Responsible for calculating and showing
// the scale in a gantt chart. This includes providing methods for
// converting dates to position in the chart as well as stroking the
// date headers (days, week, etc).
//===================================================
class GanttScale {
var $minute,$hour,$day,$week,$month,$year;
var $divider,$dividerh,$tableTitle;
var $iStartDate=-1,$iEndDate=-1;
// Number of gantt bar position (n.b not necessariliy the same as the number of bars)
// we could have on bar in position 1, and one bar in position 5 then there are two
// bars but the number of bar positions is 5
var $iVertLines=-1;
// The width of the labels (defaults to the widest of all labels)
var $iLabelWidth;
// Out image to stroke the scale to
var $iImg;
var $iTableHeaderBackgroundColor="white",$iTableHeaderFrameColor="black";
var $iTableHeaderFrameWeight=1;
var $iAvailableHeight=-1,$iVertSpacing=-1,$iVertHeaderSize=-1;
var $iDateLocale;
var $iVertLayout=GANTT_EVEN;
var $iTopPlotMargin=10,$iBottomPlotMargin=15;
var $iUsePlotWeekendBackground=true;
var $iWeekStart = 1; // Default to have weekends start on Monday
var $actinfo;
//---------------
// CONSTRUCTOR
function GanttScale(&$aImg) {
$this->iImg = &$aImg;
$this->iDateLocale = new DateLocale();
 
$this->minute = new HeaderProperty();
$this->minute->SetIntervall(15);
$this->minute->SetLabelFormatString('i');
$this->minute->SetFont(FF_FONT0);
$this->minute->grid->SetColor("gray");
 
$this->hour = new HeaderProperty();
$this->hour->SetFont(FF_FONT0);
$this->hour->SetIntervall(6);
$this->hour->SetStyle(HOURSTYLE_HM24);
$this->hour->SetLabelFormatString('H:i');
$this->hour->grid->SetColor("gray");
 
$this->day = new HeaderProperty();
$this->day->grid->SetColor("gray");
$this->day->SetLabelFormatString('l');
 
$this->week = new HeaderProperty();
$this->week->SetLabelFormatString("w%d");
$this->week->SetFont(FF_FONT1);
 
$this->month = new HeaderProperty();
$this->month->SetFont(FF_FONT1,FS_BOLD);
 
$this->year = new HeaderProperty();
$this->year->SetFont(FF_FONT1,FS_BOLD);
$this->divider=new LineProperty();
$this->dividerh=new LineProperty();
$this->dividerh->SetWeight(2);
$this->divider->SetWeight(6);
$this->divider->SetColor('gray');
$this->divider->SetStyle('fancy');
 
$this->tableTitle=new TextProperty();
$this->tableTitle->Show(false);
$this->actinfo = new GanttActivityInfo();
}
//---------------
// PUBLIC METHODS
// Specify what headers should be visible
function ShowHeaders($aFlg) {
$this->day->Show($aFlg & GANTT_HDAY);
$this->week->Show($aFlg & GANTT_HWEEK);
$this->month->Show($aFlg & GANTT_HMONTH);
$this->year->Show($aFlg & GANTT_HYEAR);
$this->hour->Show($aFlg & GANTT_HHOUR);
$this->minute->Show($aFlg & GANTT_HMIN);
 
// Make some default settings of gridlines whihc makes sense
if( $aFlg & GANTT_HWEEK ) {
$this->month->grid->Show(false);
$this->year->grid->Show(false);
}
if( $aFlg & GANTT_HHOUR ) {
$this->day->grid->SetColor("black");
}
}
// Should the weekend background stretch all the way down in the plotarea
function UseWeekendBackground($aShow) {
$this->iUsePlotWeekendBackground = $aShow;
}
// Have a range been specified?
function IsRangeSet() {
return $this->iStartDate!=-1 && $this->iEndDate!=-1;
}
// Should the layout be from top or even?
function SetVertLayout($aLayout) {
$this->iVertLayout = $aLayout;
}
// Which locale should be used?
function SetDateLocale($aLocale) {
$this->iDateLocale->Set($aLocale);
}
// Number of days we are showing
function GetNumberOfDays() {
return round(($this->iEndDate-$this->iStartDate)/SECPERDAY);
}
// The width of the actual plot area
function GetPlotWidth() {
$img=$this->iImg;
return $img->width - $img->left_margin - $img->right_margin;
}
 
// Specify the width of the titles(labels) for the activities
// (This is by default set to the minimum width enought for the
// widest title)
function SetLabelWidth($aLabelWidth) {
$this->iLabelWidth=$aLabelWidth;
}
 
// Which day should the week start?
// 0==Sun, 1==Monday, 2==Tuesday etc
function SetWeekStart($aStartDay) {
$this->iWeekStart = $aStartDay % 7;
//Recalculate the startday since this will change the week start
$this->SetRange($this->iStartDate,$this->iEndDate);
}
 
// Do we show min scale?
function IsDisplayMinute() {
return $this->minute->iShowLabels;
}
 
// Do we show day scale?
function IsDisplayHour() {
return $this->hour->iShowLabels;
}
 
// Do we show day scale?
function IsDisplayDay() {
return $this->day->iShowLabels;
}
// Do we show week scale?
function IsDisplayWeek() {
return $this->week->iShowLabels;
}
// Do we show month scale?
function IsDisplayMonth() {
return $this->month->iShowLabels;
}
// Do we show year scale?
function IsDisplayYear() {
return $this->year->iShowLabels;
}
 
// Specify spacing (in percent of bar height) between activity bars
function SetVertSpacing($aSpacing) {
$this->iVertSpacing = $aSpacing;
}
 
// Specify scale min and max date either as timestamp or as date strings
// Always round to the nearest week boundary
function SetRange($aMin,$aMax) {
$this->iStartDate = $this->NormalizeDate($aMin);
$this->iEndDate = $this->NormalizeDate($aMax);
}
 
 
// Adjust the start and end date so they fit to beginning/ending
// of the week taking the specified week start day into account.
function AdjustStartEndDay() {
 
if( !($this->IsDisplayYear() ||$this->IsDisplayMonth() || $this->IsDisplayWeek()) ) {
// Don't adjust
return;
}
 
// Get day in week for start and ending date (Sun==0)
$ds=strftime("%w",$this->iStartDate);
$de=strftime("%w",$this->iEndDate);
// We want to start on iWeekStart day. But first we subtract a week
// if the startdate is "behind" the day the week start at.
// This way we ensure that the given start date is always included
// in the range. If we don't do this the nearest correct weekday in the week
// to start at might be later than the start date.
if( $ds < $this->iWeekStart )
$d = strtotime('-7 day',$this->iStartDate);
else
$d = $this->iStartDate;
$adjdate = strtotime(($this->iWeekStart-$ds).' day',$d /*$this->iStartDate*/ );
$this->iStartDate = $adjdate;
// We want to end on the last day of the week
$preferredEndDay = ($this->iWeekStart+6)%7;
if( $preferredEndDay != $de ) {
// Solve equivalence eq: $de + x ~ $preferredDay (mod 7)
$adj = (7+($preferredEndDay - $de)) % 7;
$adjdate = strtotime("+$adj day",$this->iEndDate);
$this->iEndDate = $adjdate;
}
}
 
// Specify background for the table title area (upper left corner of the table)
function SetTableTitleBackground($aColor) {
$this->iTableHeaderBackgroundColor = $aColor;
}
 
///////////////////////////////////////
// PRIVATE Methods
// Determine the height of all the scale headers combined
function GetHeaderHeight() {
$img=$this->iImg;
$height=1;
if( $this->minute->iShowLabels ) {
$height += $this->minute->GetFontHeight($img);
$height += $this->minute->iTitleVertMargin;
}
if( $this->hour->iShowLabels ) {
$height += $this->hour->GetFontHeight($img);
$height += $this->hour->iTitleVertMargin;
}
if( $this->day->iShowLabels ) {
$height += $this->day->GetFontHeight($img);
$height += $this->day->iTitleVertMargin;
}
if( $this->week->iShowLabels ) {
$height += $this->week->GetFontHeight($img);
$height += $this->week->iTitleVertMargin;
}
if( $this->month->iShowLabels ) {
$height += $this->month->GetFontHeight($img);
$height += $this->month->iTitleVertMargin;
}
if( $this->year->iShowLabels ) {
$height += $this->year->GetFontHeight($img);
$height += $this->year->iTitleVertMargin;
}
return $height;
}
// Get width (in pixels) for a single day
function GetDayWidth() {
return ($this->GetPlotWidth()-$this->iLabelWidth+1)/$this->GetNumberOfDays();
}
 
// Get width (in pixels) for a single hour
function GetHourWidth() {
return $this->GetDayWidth() / 24 ;
}
 
function GetMinuteWidth() {
return $this->GetHourWidth() / 60 ;
}
 
// Nuber of days in a year
function GetNumDaysInYear($aYear) {
if( $this->IsLeap($aYear) )
return 366;
else
return 365;
}
// Get week number
function GetWeekNbr($aDate,$aSunStart=true) {
// We can't use the internal strftime() since it gets the weeknumber
// wrong since it doesn't follow ISO on all systems since this is
// system linrary dependent.
// Even worse is that this works differently if we are on a Windows
// or UNIX box (it even differs between UNIX boxes how strftime()
// is natively implemented)
//
// Credit to Nicolas Hoizey <nhoizey@phpheaven.net> for this elegant
// version of Week Nbr calculation.
 
$day = $this->NormalizeDate($aDate) ;
if( $aSunStart )
$day += 60*60*24;
/*-------------------------------------------------------------------------
According to ISO-8601 :
"Week 01 of a year is per definition the first week that has the Thursday in this year,
which is equivalent to the week that contains the fourth day of January.
In other words, the first week of a new year is the week that has the majority of its
days in the new year."
Be carefull, with PHP, -3 % 7 = -3, instead of 4 !!!
day of year = date("z", $day) + 1
offset to thursday = 3 - (date("w", $day) + 6) % 7
first thursday of year = 1 + (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $day)))) % 7
week number = (thursday's day of year - first thursday's day of year) / 7 + 1
---------------------------------------------------------------------------*/
$thursday = $day + 60 * 60 * 24 * (3 - (date("w", $day) + 6) % 7); // take week's thursday
$week = 1 + (date("z", $thursday) - (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $thursday)))) % 7) / 7;
return $week;
}
// Is year a leap year?
function IsLeap($aYear) {
// Is the year a leap year?
//$year = 0+date("Y",$aDate);
if( $aYear % 4 == 0)
if( !($aYear % 100 == 0) || ($aYear % 400 == 0) )
return true;
return false;
}
 
// Get current year
function GetYear($aDate) {
return 0+Date("Y",$aDate);
}
// Return number of days in a year
function GetNumDaysInMonth($aMonth,$aYear) {
$days=array(31,28,31,30,31,30,31,31,30,31,30,31);
$daysl=array(31,29,31,30,31,30,31,31,30,31,30,31);
if( $this->IsLeap($aYear))
return $daysl[$aMonth];
else
return $days[$aMonth];
}
// Get day in month
function GetMonthDayNbr($aDate) {
return 0+strftime("%d",$aDate);
}
 
// Get day in year
function GetYearDayNbr($aDate) {
return 0+strftime("%j",$aDate);
}
// Get month number
function GetMonthNbr($aDate) {
return 0+strftime("%m",$aDate);
}
// Translate a date to screen coordinates (horizontal scale)
function TranslateDate($aDate) {
//
// In order to handle the problem with Daylight savings time
// the scale written with equal number of seconds per day beginning
// with the start date. This means that we "cement" the state of
// DST as it is in the start date. If later the scale includes the
// switchover date (depends on the locale) we need to adjust back
// if the date we try to translate has a different DST status since
// we would otherwise be off by one hour.
$aDate = $this->NormalizeDate($aDate);
$tmp = localtime($aDate);
$cloc = $tmp[8];
$tmp = localtime($this->iStartDate);
$sloc = $tmp[8];
$offset = 0;
if( $sloc != $cloc) {
if( $sloc )
$offset = 3600;
else
$offset = -3600;
}
$img=$this->iImg;
return ($aDate-$this->iStartDate-$offset)/SECPERDAY*$this->GetDayWidth()+$img->left_margin+$this->iLabelWidth;;
}
 
// Get screen coordinatesz for the vertical position for a bar
function TranslateVertPos($aPos) {
$img=$this->iImg;
$ph=$this->iAvailableHeight;
if( $aPos > $this->iVertLines )
JpGraphError::RaiseL(6015,$aPos);
// 'Illegal vertical position %d'
if( $this->iVertLayout == GANTT_EVEN ) {
// Position the top bar at 1 vert spacing from the scale
return round($img->top_margin + $this->iVertHeaderSize + ($aPos+1)*$this->iVertSpacing);
}
else {
// position the top bar at 1/2 a vert spacing from the scale
return round($img->top_margin + $this->iVertHeaderSize + $this->iTopPlotMargin + ($aPos+1)*$this->iVertSpacing);
}
}
// What is the vertical spacing?
function GetVertSpacing() {
return $this->iVertSpacing;
}
// Convert a date to timestamp
function NormalizeDate($aDate) {
if( $aDate === false ) return false;
if( is_string($aDate) ) {
$t = strtotime($aDate);
if( $t === FALSE || $t === -1 ) {
JpGraphError::RaiseL(6016,$aDate);
//("Date string ($aDate) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30");
}
return $t;
}
elseif( is_int($aDate) || is_float($aDate) )
return $aDate;
else
JpGraphError::RaiseL(6017,$aDate);
//Unknown date format in GanttScale ($aDate).");
}
 
// Convert a time string to minutes
 
function TimeToMinutes($aTimeString) {
// Split in hours and minutes
$pos=strpos($aTimeString,':');
$minint=60;
if( $pos === false ) {
$hourint = $aTimeString;
$minint = 0;
}
else {
$hourint = floor(substr($aTimeString,0,$pos));
$minint = floor(substr($aTimeString,$pos+1));
}
$minint += 60 * $hourint;
return $minint;
}
 
// Stroke the day scale (including gridlines)
function StrokeMinutes($aYCoord,$getHeight=false) {
$img=$this->iImg;
$xt=$img->left_margin+$this->iLabelWidth;
$yt=$aYCoord+$img->top_margin;
if( $this->minute->iShowLabels ) {
$img->SetFont($this->minute->iFFamily,$this->minute->iFStyle,$this->minute->iFSize);
$yb = $yt + $img->GetFontHeight() +
$this->minute->iTitleVertMargin + $this->minute->iFrameWeight;
if( $getHeight ) {
return $yb - $img->top_margin;
}
$xb = $img->width-$img->right_margin+1;
$img->SetColor($this->minute->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
 
$x = $xt;
$img->SetTextAlign("center");
$day = date('w',$this->iStartDate);
$minint = $this->minute->GetIntervall() ;
if( 60 % $minint !== 0 ) {
JpGraphError::RaiseL(6018,$minint);
//'Intervall for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an intervall of '.$minint.' minutes.');
}
 
 
$n = 60 / $minint;
$datestamp = $this->iStartDate;
$width = $this->GetHourWidth() / $n ;
if( $width < 8 ) {
// TO small width to draw minute scale
JpGraphError::RaiseL(6019,$width);
//('The available width ('.$width.') for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.');
}
 
$nh = ceil(24*60 / $this->TimeToMinutes($this->hour->GetIntervall()) );
$nd = $this->GetNumberOfDays();
// Convert to intervall to seconds
$minint *= 60;
for($j=0; $j < $nd; ++$j, $day += 1, $day %= 7) {
for( $k=0; $k < $nh; ++$k ) {
for($i=0; $i < $n ;++$i, $x+=$width, $datestamp += $minint ) {
if( $day==6 || $day==0 ) {
$img->PushColor($this->day->iWeekendBackgroundColor);
if( $this->iUsePlotWeekendBackground )
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin);
else
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight);
$img->PopColor();
 
}
 
if( $day==0 )
$img->SetColor($this->day->iSundayTextColor);
else
$img->SetColor($this->day->iTextColor);
 
switch( $this->minute->iStyle ) {
case MINUTESTYLE_CUSTOM:
$txt = date($this->minute->iLabelFormStr,$datestamp);
break;
case MINUTESTYLE_MM:
default:
// 15
$txt = date('i',$datestamp);
break;
}
$img->StrokeText(round($x+$width/2),round($yb-$this->minute->iTitleVertMargin),$txt);
 
// FIXME: The rounding problem needs to be solved properly ...
//
// Fix a rounding problem the wrong way ..
// If we also have hour scale then don't draw the firsta or last
// gridline since that will be overwritten by the hour scale gridline if such exists.
// However, due to the propagation of rounding of the 'x+=width' term in the loop
// this might sometimes be one pixel of so we fix this by not drawing it.
// The proper way to fix it would be to re-calculate the scale for each step and
// not using the additive term.
if( !(($i == $n || $i==0) && $this->hour->iShowLabels && $this->hour->grid->iShow) ) {
$img->SetColor($this->minute->grid->iColor);
$img->SetLineWeight($this->minute->grid->iWeight);
$img->Line($x,$yt,$x,$yb);
$this->minute->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
}
}
}
}
$img->SetColor($this->minute->iFrameColor);
$img->SetLineWeight($this->minute->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb - $img->top_margin;
}
return $aYCoord;
}
 
// Stroke the day scale (including gridlines)
function StrokeHours($aYCoord,$getHeight=false) {
$img=$this->iImg;
$xt=$img->left_margin+$this->iLabelWidth;
$yt=$aYCoord+$img->top_margin;
if( $this->hour->iShowLabels ) {
$img->SetFont($this->hour->iFFamily,$this->hour->iFStyle,$this->hour->iFSize);
$yb = $yt + $img->GetFontHeight() +
$this->hour->iTitleVertMargin + $this->hour->iFrameWeight;
if( $getHeight ) {
return $yb - $img->top_margin;
}
$xb = $img->width-$img->right_margin+1;
$img->SetColor($this->hour->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
 
$x = $xt;
$img->SetTextAlign("center");
$tmp = $this->hour->GetIntervall() ;
$minint = $this->TimeToMinutes($tmp);
if( 1440 % $minint !== 0 ) {
JpGraphError::RaiseL(6020,$tmp);
//('Intervall for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an intervall of '.$tmp);
}
 
$n = ceil(24*60 / $minint );
$datestamp = $this->iStartDate;
$day = date('w',$this->iStartDate);
$doback = !$this->minute->iShowLabels;
$width = $this->GetDayWidth() / $n ;
for($j=0; $j < $this->GetNumberOfDays(); ++$j, $day += 1,$day %= 7) {
for($i=0; $i < $n ;++$i, $x+=$width) {
if( $day==6 || $day==0 ) {
$img->PushColor($this->day->iWeekendBackgroundColor);
if( $this->iUsePlotWeekendBackground && $doback )
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin);
else
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight);
$img->PopColor();
 
}
 
if( $day==0 )
$img->SetColor($this->day->iSundayTextColor);
else
$img->SetColor($this->day->iTextColor);
 
switch( $this->hour->iStyle ) {
case HOURSTYLE_HMAMPM:
// 1:35pm
$txt = date('g:ia',$datestamp);
break;
case HOURSTYLE_H24:
// 13
$txt = date('H',$datestamp);
break;
case HOURSTYLE_HAMPM:
$txt = date('ga',$datestamp);
break;
case HOURSTYLE_CUSTOM:
$txt = date($this->hour->iLabelFormStr,$datestamp);
break;
case HOURSTYLE_HM24:
default:
$txt = date('H:i',$datestamp);
break;
}
$img->StrokeText(round($x+$width/2),round($yb-$this->hour->iTitleVertMargin),$txt);
$img->SetColor($this->hour->grid->iColor);
$img->SetLineWeight($this->hour->grid->iWeight);
$img->Line($x,$yt,$x,$yb);
$this->hour->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
//$datestamp += $minint*60
$datestamp = mktime(date('H',$datestamp),date('i',$datestamp)+$minint,0,
date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp));
}
}
$img->SetColor($this->hour->iFrameColor);
$img->SetLineWeight($this->hour->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb - $img->top_margin;
}
return $aYCoord;
}
 
 
// Stroke the day scale (including gridlines)
function StrokeDays($aYCoord,$getHeight=false) {
$img=$this->iImg;
$daywidth=$this->GetDayWidth();
$xt=$img->left_margin+$this->iLabelWidth;
$yt=$aYCoord+$img->top_margin;
if( $this->day->iShowLabels ) {
$img->SetFont($this->day->iFFamily,$this->day->iFStyle,$this->day->iFSize);
$yb=$yt + $img->GetFontHeight() + $this->day->iTitleVertMargin + $this->day->iFrameWeight;
if( $getHeight ) {
return $yb - $img->top_margin;
}
$xb=$img->width-$img->right_margin+1;
$img->SetColor($this->day->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
 
$x = $xt;
$img->SetTextAlign("center");
$day = date('w',$this->iStartDate);
$datestamp = $this->iStartDate;
$doback = !($this->hour->iShowLabels || $this->minute->iShowLabels);
 
setlocale(LC_TIME,$this->iDateLocale->iLocale);
for($i=0; $i < $this->GetNumberOfDays(); ++$i, $x+=$daywidth, $day += 1,$day %= 7) {
if( $day==6 || $day==0 ) {
$img->SetColor($this->day->iWeekendBackgroundColor);
if( $this->iUsePlotWeekendBackground && $doback)
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,
$x+$daywidth,$img->height-$img->bottom_margin);
else
$img->FilledRectangle($x,$yt+$this->day->iFrameWeight,
$x+$daywidth,$yb-$this->day->iFrameWeight);
}
 
$mn = strftime('%m',$datestamp);
if( $mn[0]=='0' )
$mn = $mn[1];
 
switch( $this->day->iStyle ) {
case DAYSTYLE_LONG:
// "Monday"
$txt = strftime('%A',$datestamp);
break;
case DAYSTYLE_SHORT:
// "Mon"
$txt = strftime('%a',$datestamp);
break;
case DAYSTYLE_SHORTDAYDATE1:
// "Mon 23/6"
$txt = strftime('%a %d/'.$mn,$datestamp);
break;
case DAYSTYLE_SHORTDAYDATE2:
// "Mon 23 Jun"
$txt = strftime('%a %d %b',$datestamp);
break;
case DAYSTYLE_SHORTDAYDATE3:
// "Mon 23 Jun 2003"
$txt = strftime('%a %d %b %Y',$datestamp);
break;
case DAYSTYLE_LONGDAYDATE1:
// "Monday 23 Jun"
$txt = strftime('%A %d %b',$datestamp);
break;
case DAYSTYLE_LONGDAYDATE2:
// "Monday 23 Jun 2003"
$txt = strftime('%A %d %b %Y',$datestamp);
break;
case DAYSTYLE_SHORTDATE1:
// "23/6"
$txt = strftime('%d/'.$mn,$datestamp);
break;
case DAYSTYLE_SHORTDATE2:
// "23 Jun"
$txt = strftime('%d %b',$datestamp);
break;
case DAYSTYLE_SHORTDATE3:
// "Mon 23"
$txt = strftime('%a %d',$datestamp);
break;
case DAYSTYLE_SHORTDATE4:
// "23"
$txt = strftime('%d',$datestamp);
break;
case DAYSTYLE_CUSTOM:
// Custom format
$txt = strftime($this->day->iLabelFormStr,$datestamp);
break;
case DAYSTYLE_ONELETTER:
default:
// "M"
$txt = strftime('%A',$datestamp);
$txt = strtoupper($txt[0]);
break;
}
 
if( $day==0 )
$img->SetColor($this->day->iSundayTextColor);
else
$img->SetColor($this->day->iTextColor);
$img->StrokeText(round($x+$daywidth/2+1),
round($yb-$this->day->iTitleVertMargin),$txt);
$img->SetColor($this->day->grid->iColor);
$img->SetLineWeight($this->day->grid->iWeight);
$img->Line($x,$yt,$x,$yb);
$this->day->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
$datestamp = mktime(0,0,0,date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp));
//$datestamp += SECPERDAY;
}
$img->SetColor($this->day->iFrameColor);
$img->SetLineWeight($this->day->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb - $img->top_margin;
}
return $aYCoord;
}
// Stroke week header and grid
function StrokeWeeks($aYCoord,$getHeight=false) {
if( $this->week->iShowLabels ) {
$img=$this->iImg;
$yt=$aYCoord+$img->top_margin;
$img->SetFont($this->week->iFFamily,$this->week->iFStyle,$this->week->iFSize);
$yb=$yt + $img->GetFontHeight() + $this->week->iTitleVertMargin + $this->week->iFrameWeight;
 
if( $getHeight ) {
return $yb - $img->top_margin;
}
 
$xt=$img->left_margin+$this->iLabelWidth;
$weekwidth=$this->GetDayWidth()*7;
$wdays=$this->iDateLocale->GetDayAbb();
$xb=$img->width-$img->right_margin+1;
$week = $this->iStartDate;
$weeknbr=$this->GetWeekNbr($week);
$img->SetColor($this->week->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
$img->SetColor($this->week->grid->iColor);
$x = $xt;
if( $this->week->iStyle==WEEKSTYLE_WNBR ) {
$img->SetTextAlign("center");
$txtOffset = $weekwidth/2+1;
}
elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAY2 ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) {
$img->SetTextAlign("left");
$txtOffset = 3;
}
else
JpGraphError::RaiseL(6021);
//("Unknown formatting style for week.");
for($i=0; $i<$this->GetNumberOfDays()/7; ++$i, $x+=$weekwidth) {
$img->PushColor($this->week->iTextColor);
if( $this->week->iStyle==WEEKSTYLE_WNBR )
$txt = sprintf($this->week->iLabelFormStr,$weeknbr);
elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR )
$txt = date("j/n",$week);
elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY2 ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) {
$monthnbr = date("n",$week)-1;
$shortmonth = $this->iDateLocale->GetShortMonthName($monthnbr);
$txt = Date("j",$week)." ".$shortmonth;
}
 
if( $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ||
$this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) {
$w = sprintf($this->week->iLabelFormStr,$weeknbr);
$txt .= ' '.$w;
}
$img->StrokeText(round($x+$txtOffset),
round($yb-$this->week->iTitleVertMargin),$txt);
$week = strtotime('+7 day',$week);
$weeknbr = $this->GetWeekNbr($week);
$img->PopColor();
$img->SetLineWeight($this->week->grid->iWeight);
$img->Line($x,$yt,$x,$yb);
$this->week->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
}
$img->SetColor($this->week->iFrameColor);
$img->SetLineWeight($this->week->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb-$img->top_margin;
}
return $aYCoord;
}
// Format the mont scale header string
function GetMonthLabel($aMonthNbr,$year) {
$sn = $this->iDateLocale->GetShortMonthName($aMonthNbr);
$ln = $this->iDateLocale->GetLongMonthName($aMonthNbr);
switch($this->month->iStyle) {
case MONTHSTYLE_SHORTNAME:
$m=$sn;
break;
case MONTHSTYLE_LONGNAME:
$m=$ln;
break;
case MONTHSTYLE_SHORTNAMEYEAR2:
$m=$sn." '".substr("".$year,2);
break;
case MONTHSTYLE_SHORTNAMEYEAR4:
$m=$sn." ".$year;
break;
case MONTHSTYLE_LONGNAMEYEAR2:
$m=$ln." '".substr("".$year,2);
break;
case MONTHSTYLE_LONGNAMEYEAR4:
$m=$ln." ".$year;
break;
case MONTHSTYLE_FIRSTLETTER:
$m=$sn[0];
break;
}
return $m;
}
// Stroke month scale and gridlines
function StrokeMonths($aYCoord,$getHeight=false) {
if( $this->month->iShowLabels ) {
$img=$this->iImg;
$img->SetFont($this->month->iFFamily,$this->month->iFStyle,$this->month->iFSize);
$yt=$aYCoord+$img->top_margin;
$yb=$yt + $img->GetFontHeight() + $this->month->iTitleVertMargin + $this->month->iFrameWeight;
if( $getHeight ) {
return $yb - $img->top_margin;
}
$monthnbr = $this->GetMonthNbr($this->iStartDate)-1;
$xt=$img->left_margin+$this->iLabelWidth;
$xb=$img->width-$img->right_margin+1;
$img->SetColor($this->month->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
 
$img->SetLineWeight($this->month->grid->iWeight);
$img->SetColor($this->month->iTextColor);
$year = 0+strftime("%Y",$this->iStartDate);
$img->SetTextAlign("center");
if( $this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate)
&& $this->GetYear($this->iStartDate)==$this->GetYear($this->iEndDate) ) {
$monthwidth=$this->GetDayWidth()*($this->GetMonthDayNbr($this->iEndDate) - $this->GetMonthDayNbr($this->iStartDate) + 1);
}
else {
$monthwidth=$this->GetDayWidth()*($this->GetNumDaysInMonth($monthnbr,$year)-$this->GetMonthDayNbr($this->iStartDate)+1);
}
// Is it enough space to stroke the first month?
$monthName = $this->GetMonthLabel($monthnbr,$year);
if( $monthwidth >= 1.2*$img->GetTextWidth($monthName) ) {
$img->SetColor($this->month->iTextColor);
$img->StrokeText(round($xt+$monthwidth/2+1),
round($yb-$this->month->iTitleVertMargin),
$monthName);
}
$x = $xt + $monthwidth;
while( $x < $xb ) {
$img->SetColor($this->month->grid->iColor);
$img->Line($x,$yt,$x,$yb);
$this->month->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
$monthnbr++;
if( $monthnbr==12 ) {
$monthnbr=0;
$year++;
}
$monthName = $this->GetMonthLabel($monthnbr,$year);
$monthwidth=$this->GetDayWidth()*$this->GetNumDaysInMonth($monthnbr,$year);
if( $x + $monthwidth < $xb )
$w = $monthwidth;
else
$w = $xb-$x;
if( $w >= 1.2*$img->GetTextWidth($monthName) ) {
$img->SetColor($this->month->iTextColor);
$img->StrokeText(round($x+$w/2+1),
round($yb-$this->month->iTitleVertMargin),$monthName);
}
$x += $monthwidth;
}
$img->SetColor($this->month->iFrameColor);
$img->SetLineWeight($this->month->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb-$img->top_margin;
}
return $aYCoord;
}
 
// Stroke year scale and gridlines
function StrokeYears($aYCoord,$getHeight=false) {
if( $this->year->iShowLabels ) {
$img=$this->iImg;
$yt=$aYCoord+$img->top_margin;
$img->SetFont($this->year->iFFamily,$this->year->iFStyle,$this->year->iFSize);
$yb=$yt + $img->GetFontHeight() + $this->year->iTitleVertMargin + $this->year->iFrameWeight;
 
if( $getHeight ) {
return $yb - $img->top_margin;
}
 
$xb=$img->width-$img->right_margin+1;
$xt=$img->left_margin+$this->iLabelWidth;
$year = $this->GetYear($this->iStartDate);
$img->SetColor($this->year->iBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
$img->SetLineWeight($this->year->grid->iWeight);
$img->SetTextAlign("center");
if( $year == $this->GetYear($this->iEndDate) )
$yearwidth=$this->GetDayWidth()*($this->GetYearDayNbr($this->iEndDate)-$this->GetYearDayNbr($this->iStartDate)+1);
else
$yearwidth=$this->GetDayWidth()*($this->GetNumDaysInYear($year)-$this->GetYearDayNbr($this->iStartDate)+1);
// The space for a year must be at least 20% bigger than the actual text
// so we allow 10% margin on each side
if( $yearwidth >= 1.20*$img->GetTextWidth("".$year) ) {
$img->SetColor($this->year->iTextColor);
$img->StrokeText(round($xt+$yearwidth/2+1),
round($yb-$this->year->iTitleVertMargin),
$year);
}
$x = $xt + $yearwidth;
while( $x < $xb ) {
$img->SetColor($this->year->grid->iColor);
$img->Line($x,$yt,$x,$yb);
$this->year->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin);
$year += 1;
$yearwidth=$this->GetDayWidth()*$this->GetNumDaysInYear($year);
if( $x + $yearwidth < $xb )
$w = $yearwidth;
else
$w = $xb-$x;
if( $w >= 1.2*$img->GetTextWidth("".$year) ) {
$img->SetColor($this->year->iTextColor);
$img->StrokeText(round($x+$w/2+1),
round($yb-$this->year->iTitleVertMargin),
$year);
}
$x += $yearwidth;
}
$img->SetColor($this->year->iFrameColor);
$img->SetLineWeight($this->year->iFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
return $yb-$img->top_margin;
}
return $aYCoord;
}
// Stroke table title (upper left corner)
function StrokeTableHeaders($aYBottom) {
$img=$this->iImg;
$xt=$img->left_margin;
$yt=$img->top_margin;
$xb=$xt+$this->iLabelWidth;
$yb=$aYBottom+$img->top_margin;
 
if( $this->tableTitle->iShow ) {
$img->SetColor($this->iTableHeaderBackgroundColor);
$img->FilledRectangle($xt,$yt,$xb,$yb);
$this->tableTitle->Align("center","top");
$this->tableTitle->Stroke($img,$xt+($xb-$xt)/2+1,$yt+2);
$img->SetColor($this->iTableHeaderFrameColor);
$img->SetLineWeight($this->iTableHeaderFrameWeight);
$img->Rectangle($xt,$yt,$xb,$yb);
}
 
$this->actinfo->Stroke($img,$xt,$yt,$xb,$yb,$this->tableTitle->iShow);
 
 
// Draw the horizontal dividing line
$this->dividerh->Stroke($img,$xt,$yb,$img->width-$img->right_margin,$yb);
// Draw the vertical dividing line
// We do the width "manually" since we want the line only to grow
// to the left
$fancy = $this->divider->iStyle == 'fancy' ;
if( $fancy ) {
$this->divider->iStyle = 'solid';
}
 
$tmp = $this->divider->iWeight;
$this->divider->iWeight=1;
$y = $img->height-$img->bottom_margin;
for($i=0; $i < $tmp; ++$i ) {
$this->divider->Stroke($img,$xb-$i,$yt,$xb-$i,$y);
}
 
// Should we draw "fancy" divider
if( $fancy ) {
$img->SetLineWeight(1);
$img->SetColor($this->iTableHeaderFrameColor);
$img->Line($xb,$yt,$xb,$y);
$img->Line($xb-$tmp+1,$yt,$xb-$tmp+1,$y);
$img->SetColor('white');
$img->Line($xb-$tmp+2,$yt,$xb-$tmp+2,$y);
}
}
 
// Main entry point to stroke scale
function Stroke() {
if( !$this->IsRangeSet() )
JpGraphError::RaiseL(6022);
//("Gantt scale has not been specified.");
$img=$this->iImg;
 
// If minutes are displayed then hour interval must be 1
if( $this->IsDisplayMinute() && $this->hour->GetIntervall() > 1 ) {
JpGraphError::RaiseL(6023);
//('If you display both hour and minutes the hour intervall must be 1 (Otherwise it doesn\' make sense to display minutes).');
}
// Stroke all headers. As argument we supply the offset from the
// top which depends on any previous headers
// First find out the height of each header
$offy=$this->StrokeYears(0,true);
$offm=$this->StrokeMonths($offy,true);
$offw=$this->StrokeWeeks($offm,true);
$offd=$this->StrokeDays($offw,true);
$offh=$this->StrokeHours($offd,true);
$offmin=$this->StrokeMinutes($offh,true);
 
 
// ... then we can stroke them in the "backwards order to ensure that
// the larger scale gridlines is stroked over the smaller scale gridline
$this->StrokeMinutes($offh);
$this->StrokeHours($offd);
$this->StrokeDays($offw);
$this->StrokeWeeks($offm);
$this->StrokeMonths($offy);
$this->StrokeYears(0);
 
// Now when we now the oaverall size of the scale headers
// we can stroke the overall table headers
$this->StrokeTableHeaders($offmin);
// Now we can calculate the correct scaling factor for each vertical position
$this->iAvailableHeight = $img->height - $img->top_margin - $img->bottom_margin - $offd;
$this->iVertHeaderSize = $offmin;
if( $this->iVertSpacing == -1 )
$this->iVertSpacing = $this->iAvailableHeight / $this->iVertLines;
}
}
 
 
//===================================================
// CLASS GanttConstraint
// Just a structure to store all the values for a constraint
//===================================================
class GanttConstraint {
var $iConstrainType;
var $iConstrainRow;
var $iConstrainColor;
var $iConstrainArrowSize;
var $iConstrainArrowType;
 
//---------------
// CONSTRUCTOR
function GanttConstraint($aRow,$aType,$aColor,$aArrowSize,$aArrowType){
$this->iConstrainType = $aType;
$this->iConstrainRow = $aRow;
$this->iConstrainColor=$aColor;
$this->iConstrainArrowSize=$aArrowSize;
$this->iConstrainArrowType=$aArrowType;
}
}
 
 
//===================================================
// CLASS GanttPlotObject
// The common signature for a Gantt object
//===================================================
class GanttPlotObject {
var $iVPos=0; // Vertical position
var $iLabelLeftMargin=2; // Title margin
var $iStart=""; // Start date
var $title,$caption;
var $iCaptionMargin=5;
var $csimarea='',$csimtarget='',$csimwintarget='',$csimalt='';
 
var $constraints = array();
var $iConstrainPos=array();
function GanttPlotObject() {
$this->title = new TextProperty();
$this->title->Align("left","center");
$this->caption = new TextProperty();
}
 
function GetCSIMArea() {
return $this->csimarea;
}
 
function SetCSIMTarget($aTarget,$aAlt='',$aWinTarget='') {
if( !is_string($aTarget) ) {
$tv = substr(var_export($aTarget,true),0,40);
JpGraphError::RaiseL(6024,$tv);
//('CSIM Target must be specified as a string.'."\nStart of target is:\n$tv");
}
if( !is_string($aAlt) ) {
$tv = substr(var_export($aAlt,true),0,40);
JpGraphError::RaiseL(6025,$tv);
//('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv");
}
 
$this->csimtarget=$aTarget;
$this->csimwintarget=$aWinTarget;
$this->csimalt=$aAlt;
}
function SetCSIMAlt($aAlt) {
if( !is_string($aAlt) ) {
$tv = substr(var_export($aAlt,true),0,40);
JpGraphError::RaiseL(6025,$tv);
//('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv");
}
$this->csimalt=$aAlt;
}
 
function SetConstrain($aRow,$aType,$aColor='black',$aArrowSize=ARROW_S2,$aArrowType=ARROWT_SOLID) {
$this->constraints[] = new GanttConstraint($aRow, $aType, $aColor, $aArrowSize, $aArrowType);
}
 
function SetConstrainPos($xt,$yt,$xb,$yb) {
$this->iConstrainPos = array($xt,$yt,$xb,$yb);
}
 
/*
function GetConstrain() {
return array($this->iConstrainRow,$this->iConstrainType);
}
*/
function GetMinDate() {
return $this->iStart;
}
 
function GetMaxDate() {
return $this->iStart;
}
function SetCaptionMargin($aMarg) {
$this->iCaptionMargin=$aMarg;
}
 
function GetAbsHeight(&$aImg) {
return 0;
}
function GetLineNbr() {
return $this->iVPos;
}
 
function SetLabelLeftMargin($aOff) {
$this->iLabelLeftMargin=$aOff;
}
 
function StrokeActInfo(&$aImg,$aScale,$aYPos) {
$cols=array();
$aScale->actinfo->GetColStart($aImg,$cols,true);
$this->title->Stroke($aImg,$cols,$aYPos);
}
}
 
//===================================================
// CLASS Progress
// Holds parameters for the progress indicator
// displyed within a bar
//===================================================
class Progress {
var $iProgress=-1, $iColor="black", $iFillColor='black';
var $iPattern=GANTT_SOLID;
var $iDensity=98, $iHeight=0.65;
function Set($aProg) {
if( $aProg < 0.0 || $aProg > 1.0 )
JpGraphError::RaiseL(6027);
//("Progress value must in range [0, 1]");
$this->iProgress = $aProg;
}
 
function SetPattern($aPattern,$aColor="blue",$aDensity=98) {
$this->iPattern = $aPattern;
$this->iColor = $aColor;
$this->iDensity = $aDensity;
}
 
function SetFillColor($aColor) {
$this->iFillColor = $aColor;
}
function SetHeight($aHeight) {
$this->iHeight = $aHeight;
}
}
 
DEFINE('GANTT_HGRID1',0);
DEFINE('GANTT_HGRID2',1);
 
//===================================================
// CLASS HorizontalGridLine
// Responsible for drawinf horizontal gridlines and filled alternatibg rows
//===================================================
class HorizontalGridLine {
var $iGraph=NULL;
var $iRowColor1 = '', $iRowColor2 = '';
var $iShow=false;
var $line=null;
var $iStart=0; // 0=from left margin, 1=just along header
 
function HorizontalGridLine() {
$this->line = new LineProperty();
$this->line->SetColor('gray@0.4');
$this->line->SetStyle('dashed');
}
function Show($aShow=true) {
$this->iShow = $aShow;
}
 
function SetRowFillColor($aColor1,$aColor2='') {
$this->iRowColor1 = $aColor1;
$this->iRowColor2 = $aColor2;
}
 
function SetStart($aStart) {
$this->iStart = $aStart;
}
 
function Stroke(&$aImg,$aScale) {
if( ! $this->iShow ) return;
 
// Get horizontal width of line
/*
$limst = $aScale->iStartDate;
$limen = $aScale->iEndDate;
$xt = round($aScale->TranslateDate($aScale->iStartDate));
$xb = round($aScale->TranslateDate($limen));
*/
 
if( $this->iStart === 0 ) {
$xt = $aImg->left_margin-1;
}
else {
$xt = round($aScale->TranslateDate($aScale->iStartDate))+1;
}
 
$xb = $aImg->width-$aImg->right_margin;
 
$yt = round($aScale->TranslateVertPos(0));
$yb = round($aScale->TranslateVertPos(1));
$height = $yb - $yt;
 
// Loop around for all lines in the chart
for($i=0; $i < $aScale->iVertLines; ++$i ) {
$yb = $yt - $height;
$this->line->Stroke($aImg,$xt,$yb,$xb,$yb);
if( $this->iRowColor1 !== '' ) {
if( $i % 2 == 0 ) {
$aImg->PushColor($this->iRowColor1);
$aImg->FilledRectangle($xt,$yt,$xb,$yb);
$aImg->PopColor();
}
elseif( $this->iRowColor2 !== '' ) {
$aImg->PushColor($this->iRowColor2);
$aImg->FilledRectangle($xt,$yt,$xb,$yb);
$aImg->PopColor();
}
}
$yt = round($aScale->TranslateVertPos($i+1));
}
$yb = $yt - $height;
$this->line->Stroke($aImg,$xt,$yb,$xb,$yb);
}
}
 
 
//===================================================
// CLASS GanttBar
// Responsible for formatting individual gantt bars
//===================================================
class GanttBar extends GanttPlotObject {
var $iEnd;
var $iHeightFactor=0.5;
var $iFillColor="white",$iFrameColor="black";
var $iShadow=false,$iShadowColor="darkgray",$iShadowWidth=1,$iShadowFrame="black";
var $iPattern=GANTT_RDIAG,$iPatternColor="blue",$iPatternDensity=95;
var $leftMark,$rightMark;
var $progress;
//---------------
// CONSTRUCTOR
function GanttBar($aPos,$aLabel,$aStart,$aEnd,$aCaption="",$aHeightFactor=0.6) {
parent::GanttPlotObject();
$this->iStart = $aStart;
// Is the end date given as a date or as number of days added to start date?
if( is_string($aEnd) ) {
// If end date has been specified without a time we will asssume
// end date is at the end of that date
if( strpos($aEnd,':') === false )
$this->iEnd = strtotime($aEnd)+SECPERDAY-1;
else
$this->iEnd = $aEnd;
}
elseif(is_int($aEnd) || is_float($aEnd) )
$this->iEnd = strtotime($aStart)+round($aEnd*SECPERDAY);
$this->iVPos = $aPos;
$this->iHeightFactor = $aHeightFactor;
$this->title->Set($aLabel);
$this->caption = new TextProperty($aCaption);
$this->caption->Align("left","center");
$this->leftMark =new PlotMark();
$this->leftMark->Hide();
$this->rightMark=new PlotMark();
$this->rightMark->Hide();
$this->progress = new Progress();
}
//---------------
// PUBLIC METHODS
function SetShadow($aShadow=true,$aColor="gray") {
$this->iShadow=$aShadow;
$this->iShadowColor=$aColor;
}
function GetMaxDate() {
return $this->iEnd;
}
function SetHeight($aHeight) {
$this->iHeightFactor = $aHeight;
}
 
function SetColor($aColor) {
$this->iFrameColor = $aColor;
}
 
function SetFillColor($aColor) {
$this->iFillColor = $aColor;
}
 
function GetAbsHeight(&$aImg) {
if( is_int($this->iHeightFactor) || $this->leftMark->show || $this->rightMark->show ) {
$m=-1;
if( is_int($this->iHeightFactor) )
$m = $this->iHeightFactor;
if( $this->leftMark->show )
$m = max($m,$this->leftMark->width*2);
if( $this->rightMark->show )
$m = max($m,$this->rightMark->width*2);
return $m;
}
else
return -1;
}
function SetPattern($aPattern,$aColor="blue",$aDensity=95) {
$this->iPattern = $aPattern;
$this->iPatternColor = $aColor;
$this->iPatternDensity = $aDensity;
}
 
function Stroke(&$aImg,$aScale) {
$factory = new RectPatternFactory();
$prect = $factory->Create($this->iPattern,$this->iPatternColor);
$prect->SetDensity($this->iPatternDensity);
 
// If height factor is specified as a float between 0,1 then we take it as meaning
// percetage of the scale width between horizontal line.
// If it is an integer > 1 we take it to mean the absolute height in pixels
if( $this->iHeightFactor > -0.0 && $this->iHeightFactor <= 1.1)
$vs = $aScale->GetVertSpacing()*$this->iHeightFactor;
elseif(is_int($this->iHeightFactor) && $this->iHeightFactor>2 && $this->iHeightFactor < 200 )
$vs = $this->iHeightFactor;
else
JpGraphError::RaiseL(6028,$this->iHeightFactor);
//("Specified height (".$this->iHeightFactor.") for gantt bar is out of range.");
// Clip date to min max dates to show
$st = $aScale->NormalizeDate($this->iStart);
$en = $aScale->NormalizeDate($this->iEnd);
 
$limst = max($st,$aScale->iStartDate);
$limen = min($en,$aScale->iEndDate);
$xt = round($aScale->TranslateDate($limst));
$xb = round($aScale->TranslateDate($limen));
$yt = round($aScale->TranslateVertPos($this->iVPos)-$vs-($aScale->GetVertSpacing()/2-$vs/2));
$yb = round($aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2-$vs/2));
$middle = round($yt+($yb-$yt)/2);
$this->StrokeActInfo($aImg,$aScale,$middle);
 
// CSIM for title
if( ! empty($this->title->csimtarget) ) {
$colwidth = $this->title->GetColWidth($aImg);
$colstarts=array();
$aScale->actinfo->GetColStart($aImg,$colstarts,true);
$n = min(count($colwidth),count($this->title->csimtarget));
for( $i=0; $i < $n; ++$i ) {
$title_xt = $colstarts[$i];
$title_xb = $title_xt + $colwidth[$i];
$coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb";
 
if( ! empty($this->title->csimtarget[$i]) ) {
$this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\"";
 
if( ! empty($this->title->csimwintarget[$i]) ) {
$this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\" ";
}
if( ! empty($this->title->csimalt[$i]) ) {
$tmp = $this->title->csimalt[$i];
$this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimarea .= " />\n";
}
}
}
 
// Check if the bar is totally outside the current scale range
if( $en < $aScale->iStartDate || $st > $aScale->iEndDate )
return;
 
// Remember the positions for the bar
$this->SetConstrainPos($xt,$yt,$xb,$yb);
$prect->ShowFrame(false);
$prect->SetBackground($this->iFillColor);
if( $this->iShadow ) {
$aImg->SetColor($this->iFrameColor);
$aImg->ShadowRectangle($xt,$yt,$xb,$yb,$this->iFillColor,$this->iShadowWidth,$this->iShadowColor);
$prect->SetPos(new Rectangle($xt+1,$yt+1,$xb-$xt-$this->iShadowWidth-2,$yb-$yt-$this->iShadowWidth-2));
$prect->Stroke($aImg);
}
else {
$prect->SetPos(new Rectangle($xt,$yt,$xb-$xt+1,$yb-$yt+1));
$prect->Stroke($aImg);
$aImg->SetColor($this->iFrameColor);
$aImg->Rectangle($xt,$yt,$xb,$yb);
}
 
// CSIM for bar
if( ! empty($this->csimtarget) ) {
 
$coords = "$xt,$yt,$xb,$yt,$xb,$yb,$xt,$yb";
$this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtarget."\"";
if( !empty($this->csimwintarget) ) {
$this->csimarea .= " target=\"".$this->csimwintarget."\" ";
}
 
if( $this->csimalt != '' ) {
$tmp = $this->csimalt;
$this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimarea .= " />\n";
}
 
// Draw progress bar inside activity bar
if( $this->progress->iProgress > 0 ) {
$xtp = $aScale->TranslateDate($st);
$xbp = $aScale->TranslateDate($en);
$len = ($xbp-$xtp)*$this->progress->iProgress;
 
$endpos = $xtp+$len;
// Is the the progress bar visible after the start date?
if( $endpos > $xt ) {
 
// Take away the length of the progress that is not visible (before the start date)
$len -= ($xt-$xtp);
 
// Is the the progress bar visible after the start date?
if( $xtp < $xt )
$xtp = $xt;
// Make sure that the progess bar doesn't extend over the end date
if( $xtp+$len-1 > $xb )
$len = $xb - $xtp ;
$prog = $factory->Create($this->progress->iPattern,$this->progress->iColor);
$prog->SetDensity($this->progress->iDensity);
$prog->SetBackground($this->progress->iFillColor);
$barheight = ($yb-$yt+1);
if( $this->iShadow )
$barheight -= $this->iShadowWidth;
$progressheight = floor($barheight*$this->progress->iHeight);
$marg = ceil(($barheight-$progressheight)/2);
$pos = new Rectangle($xtp,$yt + $marg, $len,$barheight-2*$marg);
$prog->SetPos($pos);
$prog->Stroke($aImg);
}
}
// We don't plot the end mark if the bar has been capped
if( $limst == $st ) {
$y = $middle;
// We treat the RIGHT and LEFT triangle mark a little bi
// special so that these marks are placed right under the
// bar.
if( $this->leftMark->GetType() == MARK_LEFTTRIANGLE ) {
$y = $yb ;
}
$this->leftMark->Stroke($aImg,$xt,$y);
}
if( $limen == $en ) {
$y = $middle;
// We treat the RIGHT and LEFT triangle mark a little bi
// special so that these marks are placed right under the
// bar.
if( $this->rightMark->GetType() == MARK_RIGHTTRIANGLE ) {
$y = $yb ;
}
$this->rightMark->Stroke($aImg,$xb,$y);
$margin = $this->iCaptionMargin;
if( $this->rightMark->show )
$margin += $this->rightMark->GetWidth();
$this->caption->Stroke($aImg,$xb+$margin,$middle);
}
}
}
 
//===================================================
// CLASS MileStone
// Responsible for formatting individual milestones
//===================================================
class MileStone extends GanttPlotObject {
var $mark;
//---------------
// CONSTRUCTOR
function MileStone($aVPos,$aLabel,$aDate,$aCaption="") {
GanttPlotObject::GanttPlotObject();
$this->caption->Set($aCaption);
$this->caption->Align("left","center");
$this->caption->SetFont(FF_FONT1,FS_BOLD);
$this->title->Set($aLabel);
$this->title->SetColor("darkred");
$this->mark = new PlotMark();
$this->mark->SetWidth(10);
$this->mark->SetType(MARK_DIAMOND);
$this->mark->SetColor("darkred");
$this->mark->SetFillColor("darkred");
$this->iVPos = $aVPos;
$this->iStart = $aDate;
}
//---------------
// PUBLIC METHODS
function GetAbsHeight(&$aImg) {
return max($this->title->GetHeight($aImg),$this->mark->GetWidth());
}
function Stroke(&$aImg,$aScale) {
// Put the mark in the middle at the middle of the day
$d = $aScale->NormalizeDate($this->iStart)+SECPERDAY/2;
$x = $aScale->TranslateDate($d);
$y = $aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2);
 
$this->StrokeActInfo($aImg,$aScale,$y);
 
// CSIM for title
if( ! empty($this->title->csimtarget) ) {
$yt = round($y - $this->title->GetHeight($aImg)/2);
$yb = round($y + $this->title->GetHeight($aImg)/2);
 
$colwidth = $this->title->GetColWidth($aImg);
$colstarts=array();
$aScale->actinfo->GetColStart($aImg,$colstarts,true);
$n = min(count($colwidth),count($this->title->csimtarget));
for( $i=0; $i < $n; ++$i ) {
$title_xt = $colstarts[$i];
$title_xb = $title_xt + $colwidth[$i];
$coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb";
if( !empty($this->title->csimtarget[$i]) ) {
 
$this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\"";
 
if( !empty($this->title->csimwintarget[$i]) ) {
$this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\"";
}
 
if( ! empty($this->title->csimalt[$i]) ) {
$tmp = $this->title->csimalt[$i];
$this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimarea .= " />\n";
 
}
}
}
 
if( $d < $aScale->iStartDate || $d > $aScale->iEndDate )
return;
 
// Remember the coordinates for any constrains linking to
// this milestone
$w = $this->mark->GetWidth()/2;
$this->SetConstrainPos($x,round($y-$w),$x,round($y+$w));
// Setup CSIM
if( $this->csimtarget != '' ) {
$this->mark->SetCSIMTarget( $this->csimtarget );
$this->mark->SetCSIMAlt( $this->csimalt );
}
$this->mark->Stroke($aImg,$x,$y);
$this->caption->Stroke($aImg,$x+$this->mark->width/2+$this->iCaptionMargin,$y);
 
$this->csimarea .= $this->mark->GetCSIMAreas();
}
}
 
 
//===================================================
// CLASS GanttVLine
// Responsible for formatting individual milestones
//===================================================
 
class TextPropertyBelow extends TextProperty {
function TextPropertyBelow($aTxt='') {
parent::TextProperty($aTxt);
}
 
function GetColWidth(&$aImg,$margin) {
// Since we are not stroking the title in the columns
// but rather under the graph we want this to return 0.
return array(0);
}
}
 
class GanttVLine extends GanttPlotObject {
 
var $iLine,$title_margin=3;
var $iDayOffset=1; // Defult to right edge of day
//---------------
// CONSTRUCTOR
function GanttVLine($aDate,$aTitle="",$aColor="black",$aWeight=3,$aStyle="dashed") {
GanttPlotObject::GanttPlotObject();
$this->iLine = new LineProperty();
$this->iLine->SetColor($aColor);
$this->iLine->SetWeight($aWeight);
$this->iLine->SetStyle($aStyle);
$this->iStart = $aDate;
$this->title = new TextPropertyBelow();
$this->title->Set($aTitle);
}
 
//---------------
// PUBLIC METHODS
 
function SetDayOffset($aOff=0.5) {
if( $aOff < 0.0 || $aOff > 1.0 )
JpGraphError::RaiseL(6029);
//("Offset for vertical line must be in range [0,1]");
$this->iDayOffset = $aOff;
}
function SetTitleMargin($aMarg) {
$this->title_margin = $aMarg;
}
function Stroke(&$aImg,$aScale) {
$d = $aScale->NormalizeDate($this->iStart);
if( $d < $aScale->iStartDate || $d > $aScale->iEndDate )
return;
if($this->iDayOffset != 0.0)
$d += 24*60*60*$this->iDayOffset;
$x = $aScale->TranslateDate($d);
$y1 = $aScale->iVertHeaderSize+$aImg->top_margin;
$y2 = $aImg->height - $aImg->bottom_margin;
$this->iLine->Stroke($aImg,$x,$y1,$x,$y2);
$this->title->Align("center","top");
$this->title->Stroke($aImg,$x,$y2+$this->title_margin);
}
}
 
//===================================================
// CLASS LinkArrow
// Handles the drawing of a an arrow
//===================================================
class LinkArrow {
var $ix,$iy;
var $isizespec = array(
array(2,3),array(3,5),array(3,8),array(6,15),array(8,22));
var $iDirection=ARROW_DOWN,$iType=ARROWT_SOLID,$iSize=ARROW_S2;
var $iColor='black';
 
function LinkArrow($x,$y,$aDirection,$aType=ARROWT_SOLID,$aSize=ARROW_S2) {
$this->iDirection = $aDirection;
$this->iType = $aType;
$this->iSize = $aSize;
$this->ix = $x;
$this->iy = $y;
}
function SetColor($aColor) {
$this->iColor = $aColor;
}
 
function SetSize($aSize) {
$this->iSize = $aSize;
}
 
function SetType($aType) {
$this->iType = $aType;
}
 
function Stroke(&$aImg) {
list($dx,$dy) = $this->isizespec[$this->iSize];
$x = $this->ix;
$y = $this->iy;
switch ( $this->iDirection ) {
case ARROW_DOWN:
$c = array($x,$y,$x-$dx,$y-$dy,$x+$dx,$y-$dy,$x,$y);
break;
case ARROW_UP:
$c = array($x,$y,$x-$dx,$y+$dy,$x+$dx,$y+$dy,$x,$y);
break;
case ARROW_LEFT:
$c = array($x,$y,$x+$dy,$y-$dx,$x+$dy,$y+$dx,$x,$y);
break;
case ARROW_RIGHT:
$c = array($x,$y,$x-$dy,$y-$dx,$x-$dy,$y+$dx,$x,$y);
break;
default:
JpGraphError::RaiseL(6030);
//('Unknown arrow direction for link.');
die();
break;
}
$aImg->SetColor($this->iColor);
switch( $this->iType ) {
case ARROWT_SOLID:
$aImg->FilledPolygon($c);
break;
case ARROWT_OPEN:
$aImg->Polygon($c);
break;
default:
JpGraphError::RaiseL(6031);
//('Unknown arrow type for link.');
die();
break;
}
}
}
 
//===================================================
// CLASS GanttLink
// Handles the drawing of a link line between 2 points
//===================================================
 
class GanttLink {
var $ix1,$ix2,$iy1,$iy2;
var $iPathType=2,$iPathExtend=15;
var $iColor='black',$iWeight=1;
var $iArrowSize=ARROW_S2,$iArrowType=ARROWT_SOLID;
 
function GanttLink($x1=0,$y1=0,$x2=0,$y2=0) {
$this->ix1 = $x1;
$this->ix2 = $x2;
$this->iy1 = $y1;
$this->iy2 = $y2;
}
 
function SetPos($x1,$y1,$x2,$y2) {
$this->ix1 = $x1;
$this->ix2 = $x2;
$this->iy1 = $y1;
$this->iy2 = $y2;
}
 
function SetPath($aPath) {
$this->iPathType = $aPath;
}
 
function SetColor($aColor) {
$this->iColor = $aColor;
}
 
function SetArrow($aSize,$aType=ARROWT_SOLID) {
$this->iArrowSize = $aSize;
$this->iArrowType = $aType;
}
function SetWeight($aWeight) {
$this->iWeight = $aWeight;
}
 
function Stroke(&$aImg) {
// The way the path for the arrow is constructed is partly based
// on some heuristics. This is not an exact science but draws the
// path in a way that, for me, makes esthetic sence. For example
// if the start and end activities are very close we make a small
// detour to endter the target horixontally. If there are more
// space between axctivities then no suh detour is made and the
// target is "hit" directly vertical. I have tried to keep this
// simple. no doubt this could become almost infinitive complex
// and have some real AI. Feel free to modify this.
// This will no-doubt be tweaked as times go by. One design aim
// is to avoid having the user choose what types of arrow
// he wants.
 
// The arrow is drawn between (x1,y1) to (x2,y2)
$x1 = $this->ix1 ;
$x2 = $this->ix2 ;
$y1 = $this->iy1 ;
$y2 = $this->iy2 ;
 
// Depending on if the target is below or above we have to
// handle thi different.
if( $y2 > $y1 ) {
$arrowtype = ARROW_DOWN;
$midy = round(($y2-$y1)/2+$y1);
if( $x2 > $x1 ) {
switch ( $this->iPathType ) {
case 0:
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
break;
case 1:
case 2:
case 3:
$c = array($x1,$y1,$x2,$y1,$x2,$y2);
break;
default:
JpGraphError::RaiseL(6032,$this->iPathType);
//('Internal error: Unknown path type (='.$this->iPathType .') specified for link.');
exit(1);
break;
}
}
else {
switch ( $this->iPathType ) {
case 0:
case 1:
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
break;
case 2:
// Always extend out horizontally a bit from the first point
// If we draw a link back in time (end to start) and the bars
// are very close we also change the path so it comes in from
// the left on the activity
$c = array($x1,$y1,$x1+$this->iPathExtend,$y1,
$x1+$this->iPathExtend,$midy,
$x2,$midy,$x2,$y2);
break;
case 3:
if( $y2-$midy < 6 ) {
$c = array($x1,$y1,$x1,$midy,
$x2-$this->iPathExtend,$midy,
$x2-$this->iPathExtend,$y2,
$x2,$y2);
$arrowtype = ARROW_RIGHT;
}
else {
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
}
break;
default:
JpGraphError::RaiseL(6032,$this->iPathType);
//('Internal error: Unknown path type specified for link.');
exit(1);
break;
}
}
$arrow = new LinkArrow($x2,$y2,$arrowtype);
}
else {
// Y2 < Y1
$arrowtype = ARROW_UP;
$midy = round(($y1-$y2)/2+$y2);
if( $x2 > $x1 ) {
switch ( $this->iPathType ) {
case 0:
case 1:
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
break;
case 3:
if( $midy-$y2 < 8 ) {
$arrowtype = ARROW_RIGHT;
$c = array($x1,$y1,$x1,$y2,$x2,$y2);
}
else {
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
}
break;
default:
JpGraphError::RaiseL(6032,$this->iPathType);
//('Internal error: Unknown path type specified for link.');
break;
}
}
else {
switch ( $this->iPathType ) {
case 0:
case 1:
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
break;
case 2:
// Always extend out horizontally a bit from the first point
$c = array($x1,$y1,$x1+$this->iPathExtend,$y1,
$x1+$this->iPathExtend,$midy,
$x2,$midy,$x2,$y2);
break;
case 3:
if( $midy-$y2 < 16 ) {
$arrowtype = ARROW_RIGHT;
$c = array($x1,$y1,$x1,$midy,$x2-$this->iPathExtend,$midy,
$x2-$this->iPathExtend,$y2,
$x2,$y2);
}
else {
$c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2);
}
break;
default:
JpGraphError::RaiseL(6032,$this->iPathType);
//('Internal error: Unknown path type specified for link.');
break;
}
}
$arrow = new LinkArrow($x2,$y2,$arrowtype);
}
$aImg->SetColor($this->iColor);
$aImg->SetLineWeight($this->iWeight);
$aImg->Polygon($c);
$aImg->SetLineWeight(1);
$arrow->SetColor($this->iColor);
$arrow->SetSize($this->iArrowSize);
$arrow->SetType($this->iArrowType);
$arrow->Stroke($aImg);
}
}
 
// <EOF>
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_date.php
New file
0,0 → 1,497
<?php
/*=======================================================================
// File: JPGRAPH_DATE.PHP
// Description: Classes to handle Date scaling
// Created: 2005-05-02
// Ver: $Id: jpgraph_date.php 911 2007-09-26 21:00:09Z 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 {
var $date_format = '';
var $iStartAlign = false, $iEndAlign = false;
var $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 AdjustForDST($aFlg=true) {
$this->ticks->AdjustForDST($aFlg);
}
 
 
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) {
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);
}
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_mgraph.php
New file
0,0 → 1,381
<?php
/*=======================================================================
// File: JPGRAPH_MGRAPH.PHP
// Description: Class to handle multiple graphs in the same image
// Created: 2006-01-15
// Ver: $Id: jpgraph_mgraph.php 1011 2008-06-23 15:01:51Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
//=============================================================================
// 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( is_numeric($aCenter_aX) ) {
$aX=$aCenter_aX;
}
 
// Get extension to determine image type
$e = explode('.',$aFileName);
if( !$e ) {
JpGraphError::RaiseL(12002,$aFileName);
//('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::RaiseL(12003,$aImgFormat,$aFileName);
//('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::RaiseL(12004,$aFile);//('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::RaiseL(12005,$aFile);
//(" 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::RaiseL(12006,$aWidth,$aHeight);
//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)");
}
$this->img = @imagecreatetruecolor($aWidth, $aHeight);
if( $this->img < 1 ) {
JpGraphError::RaiseL(12011);
// die("<b>JpGraph Error:</b> Can't create truecolor image. Check that you really have GD2 library installed.");
}
ImageAlphaBlending($this->img,true);
}
 
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::RaiseL(12007);
//('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::RaiseL(12008);
//(" Your PHP (and GD-lib) installation does not appear to support any known graphic formats.".
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::RaiseL(12009,$aFormat);
//(" 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::RaiseL(12010,$aFile);
//("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 {
if( $aFileName != '' ) {
$this->Stream($aFileName);
}
else {
$this->Headers();
$this->Stream();
}
}
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph.php
New file
0,0 → 1,5950
<?php
//=======================================================================
// File: JPGRAPH.PHP
// Description: PHP Graph Plotting library. Base module.
// Created: 2001-01-08
// Ver: $Id: jpgraph.php 1076 2008-09-19 15:43:22Z ljp $
//
// Copyright 2006 (c) Aditus Consulting. All rights reserved.
//========================================================================
 
require_once('jpg-config.inc.php');
require_once('jpgraph_errhandler.inc.php');
require_once('gd_image.inc.php');
require_once('jpgraph_ttf.inc.php');
require_once 'jpgraph_gradient.php';
 
// Version info
DEFINE('JPG_VERSION','1.26.1-dev');
 
// Minimum required PHP version
DEFINE('MIN_PHPVERSION','4.3.1');
 
//------------------------------------------------------------------------
// Automatic settings of path for cache and font directory
// if they have not been previously specified
//------------------------------------------------------------------------
if(USE_CACHE) {
if (!defined('CACHE_DIR')) {
if ( strstr( PHP_OS, 'WIN') ) {
if( empty($_SERVER['TEMP']) ) {
$t = new ErrMsgText();
$msg = $t->Get(11,$file,$lineno);
die($msg);
}
else {
DEFINE('CACHE_DIR', $_SERVER['TEMP'] . '/');
}
} else {
DEFINE('CACHE_DIR','/tmp/jpgraph_cache/');
}
}
}
elseif( !defined('CACHE_DIR') ) {
DEFINE('CACHE_DIR', '');
}
 
if (!defined('TTF_DIR')) {
if (strstr( PHP_OS, 'WIN') ) {
$sroot = getenv('SystemRoot');
if( empty($sroot) ) {
$t = new ErrMsgText();
$msg = $t->Get(12,$file,$lineno);
die($msg);
}
else {
DEFINE('TTF_DIR', $sroot.'/fonts/');
}
} else {
DEFINE('TTF_DIR','/usr/X11R6/lib/X11/fonts/truetype/');
}
}
 
if (!defined('MBTTF_DIR')) {
if (strstr( PHP_OS, 'WIN') ) {
$sroot = getenv('SystemRoot');
if( empty($sroot) ) {
$t = new ErrMsgText();
$msg = $t->Get(12,$file,$lineno);
die($msg);
}
else {
DEFINE('TTF_DIR', $sroot.'/fonts/');
}
} else {
DEFINE('MBTTF_DIR','/usr/share/fonts/ja/TrueType/');
}
}
 
//------------------------------------------------------------------
// Constants which are used as parameters for the method calls
//------------------------------------------------------------------
 
// Tick density
DEFINE("TICKD_DENSE",1);
DEFINE("TICKD_NORMAL",2);
DEFINE("TICKD_SPARSE",3);
DEFINE("TICKD_VERYSPARSE",4);
 
// Side for ticks and labels.
DEFINE("SIDE_LEFT",-1);
DEFINE("SIDE_RIGHT",1);
DEFINE("SIDE_DOWN",-1);
DEFINE("SIDE_BOTTOM",-1);
DEFINE("SIDE_UP",1);
DEFINE("SIDE_TOP",1);
 
// Legend type stacked vertical or horizontal
DEFINE("LEGEND_VERT",0);
DEFINE("LEGEND_HOR",1);
 
// Mark types for plot marks
DEFINE("MARK_SQUARE",1);
DEFINE("MARK_UTRIANGLE",2);
DEFINE("MARK_DTRIANGLE",3);
DEFINE("MARK_DIAMOND",4);
DEFINE("MARK_CIRCLE",5);
DEFINE("MARK_FILLEDCIRCLE",6);
DEFINE("MARK_CROSS",7);
DEFINE("MARK_STAR",8);
DEFINE("MARK_X",9);
DEFINE("MARK_LEFTTRIANGLE",10);
DEFINE("MARK_RIGHTTRIANGLE",11);
DEFINE("MARK_FLASH",12);
DEFINE("MARK_IMG",13);
DEFINE("MARK_FLAG1",14);
DEFINE("MARK_FLAG2",15);
DEFINE("MARK_FLAG3",16);
DEFINE("MARK_FLAG4",17);
 
// Builtin images
DEFINE("MARK_IMG_PUSHPIN",50);
DEFINE("MARK_IMG_SPUSHPIN",50);
DEFINE("MARK_IMG_LPUSHPIN",51);
DEFINE("MARK_IMG_DIAMOND",52);
DEFINE("MARK_IMG_SQUARE",53);
DEFINE("MARK_IMG_STAR",54);
DEFINE("MARK_IMG_BALL",55);
DEFINE("MARK_IMG_SBALL",55);
DEFINE("MARK_IMG_MBALL",56);
DEFINE("MARK_IMG_LBALL",57);
DEFINE("MARK_IMG_BEVEL",58);
 
// Inline defines
DEFINE("INLINE_YES",1);
DEFINE("INLINE_NO",0);
 
// Format for background images
DEFINE("BGIMG_FILLPLOT",1);
DEFINE("BGIMG_FILLFRAME",2);
DEFINE("BGIMG_COPY",3);
DEFINE("BGIMG_CENTER",4);
 
// Depth of objects
DEFINE("DEPTH_BACK",0);
DEFINE("DEPTH_FRONT",1);
 
// Direction
DEFINE("VERTICAL",1);
DEFINE("HORIZONTAL",0);
 
// Axis styles for scientific style axis
DEFINE('AXSTYLE_SIMPLE',1);
DEFINE('AXSTYLE_BOXIN',2);
DEFINE('AXSTYLE_BOXOUT',3);
DEFINE('AXSTYLE_YBOXIN',4);
DEFINE('AXSTYLE_YBOXOUT',5);
 
// Style for title backgrounds
DEFINE('TITLEBKG_STYLE1',1);
DEFINE('TITLEBKG_STYLE2',2);
DEFINE('TITLEBKG_STYLE3',3);
DEFINE('TITLEBKG_FRAME_NONE',0);
DEFINE('TITLEBKG_FRAME_FULL',1);
DEFINE('TITLEBKG_FRAME_BOTTOM',2);
DEFINE('TITLEBKG_FRAME_BEVEL',3);
DEFINE('TITLEBKG_FILLSTYLE_HSTRIPED',1);
DEFINE('TITLEBKG_FILLSTYLE_VSTRIPED',2);
DEFINE('TITLEBKG_FILLSTYLE_SOLID',3);
 
// Style for background gradient fills
DEFINE('BGRAD_FRAME',1);
DEFINE('BGRAD_MARGIN',2);
DEFINE('BGRAD_PLOT',3);
 
// Width of tab titles
DEFINE('TABTITLE_WIDTHFIT',0);
DEFINE('TABTITLE_WIDTHFULL',-1);
 
// Defines for 3D skew directions
DEFINE('SKEW3D_UP',0);
DEFINE('SKEW3D_DOWN',1);
DEFINE('SKEW3D_LEFT',2);
DEFINE('SKEW3D_RIGHT',3);
 
// For internal use only
DEFINE("_JPG_DEBUG",false);
DEFINE("_FORCE_IMGTOFILE",false);
DEFINE("_FORCE_IMGDIR",'/tmp/jpgimg/');
 
 
function CheckPHPVersion($aMinVersion)
{
list($majorC, $minorC, $editC) = split('[/.-]', PHP_VERSION);
list($majorR, $minorR, $editR) = split('[/.-]', $aMinVersion);
if ($majorC > $majorR) return true;
if ($majorC < $majorR) return false;
// same major - check minor
if ($minorC > $minorR) return true;
if ($minorC < $minorR) return false;
// and same minor
if ($editC >= $editR) return true;
return true;
}
 
//
// Make sure PHP version is high enough
//
if( !CheckPHPVersion(MIN_PHPVERSION) ) {
JpGraphError::RaiseL(13,PHP_VERSION,MIN_PHPVERSION);
}
 
//
// Routine to determine if GD1 or GD2 is installed
//
function CheckGDVersion() {
if( !function_exists("imagetypes") || !function_exists('imagecreatefromstring') )
return 0;
$GDfuncList = get_extension_funcs('gd');
if( !$GDfuncList )
return 0 ;
else {
if( in_array('imagegd2',$GDfuncList) &&
in_array('imagecreatetruecolor',$GDfuncList))
return 2;
else
return 1;
}
}
 
//
// Check what version of the GD library is installed.
//
$gdversion = CheckGDVersion();
if( $gdversion != 2 ) {
JpGraphError::RaiseL(25002);
//(" Your PHP installation does not seem to have the required GD 2.x library. Please see the PHP documentation on how to install and enable the GD library.");
}
 
//
// Setup PHP error handler
//
function _phpErrorHandler($errno,$errmsg,$filename, $linenum, $vars) {
// Respect current error level
if( $errno & error_reporting() ) {
JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg);
}
}
 
if( INSTALL_PHP_ERR_HANDLER ) {
set_error_handler("_phpErrorHandler");
}
 
//
//Check if there were any warnings, perhaps some wrong includes by the user
//
if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG &&
!preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg'])) {
JpGraphError::RaiseL(25004,$GLOBALS['php_errormsg']);
}
 
 
// Useful mathematical function
function sign($a) {return $a >= 0 ? 1 : -1;}
 
// Utility function to generate an image name based on the filename we
// are running from and assuming we use auto detection of graphic format
// (top level), i.e it is safe to call this function
// from a script that uses JpGraph
function GenImgName() {
global $_SERVER;
 
// Determine what format we should use when we save the images
$supported = imagetypes();
if( $supported & IMG_PNG ) $img_format="png";
elseif( $supported & IMG_GIF ) $img_format="gif";
elseif( $supported & IMG_JPG ) $img_format="jpeg";
elseif( $supported & IMG_WBMP ) $img_format="wbmp";
elseif( $supported & IMG_XPM ) $img_format="xpm";
 
if( !isset($_SERVER['PHP_SELF']) )
JpGraphError::RaiseL(25005);
//(" Can't access PHP_SELF, PHP global variable. You can't run PHP from command line if you want to use the 'auto' naming of cache or image files.");
$fname = basename($_SERVER['PHP_SELF']);
if( !empty($_SERVER['QUERY_STRING']) ) {
$q = @$_SERVER['QUERY_STRING'];
$fname .= '_'.preg_replace("/\W/", "_", $q).'.'.$img_format;
}
else {
$fname = substr($fname,0,strlen($fname)-4).'.'.$img_format;
}
return $fname;
}
 
//===================================================
// CLASS JpgTimer
// Description: General timing utility class to handle
// time measurement of generating graphs. Multiple
// timers can be started.
//===================================================
class JpgTimer {
var $start;
var $idx;
//---------------
// CONSTRUCTOR
function JpgTimer() {
$this->idx=0;
}
 
//---------------
// PUBLIC METHODS
 
// Push a new timer start on stack
function Push() {
list($ms,$s)=explode(" ",microtime());
$this->start[$this->idx++]=floor($ms*1000) + 1000*$s;
}
 
// Pop the latest timer start and return the diff with the
// current time
function Pop() {
assert($this->idx>0);
list($ms,$s)=explode(" ",microtime());
$etime=floor($ms*1000) + (1000*$s);
$this->idx--;
return $etime-$this->start[$this->idx];
}
} // Class
 
$gJpgBrandTiming = BRAND_TIMING;
//===================================================
// CLASS DateLocale
// Description: Hold localized text used in dates
//===================================================
class DateLocale {
var $iLocale = 'C'; // environmental locale be used by default
 
var $iDayAbb = null;
var $iShortDay = null;
var $iShortMonth = null;
var $iMonthName = null;
 
//---------------
// CONSTRUCTOR
function DateLocale() {
settype($this->iDayAbb, 'array');
settype($this->iShortDay, 'array');
settype($this->iShortMonth, 'array');
settype($this->iMonthName, 'array');
 
 
$this->Set('C');
}
 
//---------------
// PUBLIC METHODS
function Set($aLocale) {
if ( in_array($aLocale, array_keys($this->iDayAbb)) ){
$this->iLocale = $aLocale;
return TRUE; // already cached nothing else to do!
}
 
$pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME
 
if (is_array($aLocale)) {
foreach ($aLocale as $loc) {
$res = @setlocale(LC_TIME, $loc);
if ( $res ) {
$aLocale = $loc;
break;
}
}
}
else {
$res = @setlocale(LC_TIME, $aLocale);
}
if ( ! $res ){
JpGraphError::RaiseL(25007,$aLocale);
//("You are trying to use the locale ($aLocale) which your PHP installation does not support. Hint: Use '' to indicate the default locale for this geographic region.");
return FALSE;
}
$this->iLocale = $aLocale;
 
for ( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ){
$day = strftime('%a', strtotime("$ofs day"));
$day{0} = strtoupper($day{0});
$this->iDayAbb[$aLocale][]= $day{0};
$this->iShortDay[$aLocale][]= $day;
}
 
for($i=1; $i<=12; ++$i) {
list($short ,$full) = explode('|', strftime("%b|%B",strtotime("2001-$i-01")));
$this->iShortMonth[$aLocale][] = ucfirst($short);
$this->iMonthName [$aLocale][] = ucfirst($full);
}
 
// Return to original locale
setlocale(LC_TIME, $pLocale);
 
return TRUE;
}
 
 
function GetDayAbb() {
return $this->iDayAbb[$this->iLocale];
}
function GetShortDay() {
return $this->iShortDay[$this->iLocale];
}
 
function GetShortMonth() {
return $this->iShortMonth[$this->iLocale];
}
function GetShortMonthName($aNbr) {
return $this->iShortMonth[$this->iLocale][$aNbr];
}
 
function GetLongMonthName($aNbr) {
return $this->iMonthName[$this->iLocale][$aNbr];
}
 
function GetMonth() {
return $this->iMonthName[$this->iLocale];
}
}
 
$gDateLocale = new DateLocale();
$gJpgDateLocale = new DateLocale();
 
 
//=======================================================
// CLASS Footer
// Description: Encapsulates the footer line in the Graph
//=======================================================
class Footer {
var $left,$center,$right;
var $iLeftMargin = 3;
var $iRightMargin = 3;
var $iBottomMargin = 3;
 
function Footer() {
$this->left = new Text();
$this->left->ParagraphAlign('left');
$this->center = new Text();
$this->center->ParagraphAlign('center');
$this->right = new Text();
$this->right->ParagraphAlign('right');
}
 
function Stroke(&$aImg) {
$y = $aImg->height - $this->iBottomMargin;
$x = $this->iLeftMargin;
$this->left->Align('left','bottom');
$this->left->Stroke($aImg,$x,$y);
 
$x = ($aImg->width - $this->iLeftMargin - $this->iRightMargin)/2;
$this->center->Align('center','bottom');
$this->center->Stroke($aImg,$x,$y);
 
$x = $aImg->width - $this->iRightMargin;
$this->right->Align('right','bottom');
$this->right->Stroke($aImg,$x,$y);
}
}
 
 
//===================================================
// CLASS Graph
// Description: Main class to handle graphs
//===================================================
class Graph {
var $cache=null; // Cache object (singleton)
var $img=null; // Img object (singleton)
var $plots=array(); // Array of all plot object in the graph (for Y 1 axis)
var $y2plots=array();// Array of all plot object in the graph (for Y 2 axis)
var $ynplots=array();
var $xscale=null; // X Scale object (could be instance of LinearScale or LogScale
var $yscale=null,$y2scale=null, $ynscale=array();
var $iIcons = array(); // Array of Icons to add to
var $cache_name; // File name to be used for the current graph in the cache directory
var $xgrid=null; // X Grid object (linear or logarithmic)
var $ygrid=null,$y2grid=null;
var $doframe=true,$frame_color=array(0,0,0), $frame_weight=1; // Frame around graph
var $boxed=false, $box_color=array(0,0,0), $box_weight=1; // Box around plot area
var $doshadow=false,$shadow_width=4,$shadow_color=array(102,102,102); // Shadow for graph
var $xaxis=null; // X-axis (instane of Axis class)
var $yaxis=null, $y2axis=null, $ynaxis=array(); // Y axis (instance of Axis class)
var $margin_color=array(200,200,200); // Margin color of graph
var $plotarea_color=array(255,255,255); // Plot area color
var $title,$subtitle,$subsubtitle; // Title and subtitle(s) text object
var $axtype="linlin"; // Type of axis
var $xtick_factor,$ytick_factor; // Factot to determine the maximum number of ticks depending on the plot with
var $texts=null, $y2texts=null; // Text object to ge shown in the graph
var $lines=null, $y2lines=null;
var $bands=null, $y2bands=null;
var $text_scale_off=0, $text_scale_abscenteroff=-1; // Text scale offset in fractions and for centering bars in absolute pixels
var $background_image="",$background_image_type=-1,$background_image_format="png";
var $inline;
var $showcsim=0,$csimcolor="red"; //debug stuff, draw the csim boundaris on the image if <>0
var $grid_depth=DEPTH_BACK; // Draw grid under all plots as default
var $iAxisStyle = AXSTYLE_SIMPLE;
var $iCSIMdisplay=false,$iHasStroked = false;
var $footer;
var $csimcachename = '', $csimcachetimeout = 0, $iCSIMImgAlt='';
var $iDoClipping = false;
var $y2orderback=true;
var $tabtitle;
var $bkg_gradtype=-1,$bkg_gradstyle=BGRAD_MARGIN;
var $bkg_gradfrom='navy', $bkg_gradto='silver';
var $titlebackground = false;
var $titlebackground_color = 'lightblue',
$titlebackground_style = 1,
$titlebackground_framecolor = 'blue',
$titlebackground_framestyle = 2,
$titlebackground_frameweight = 1,
$titlebackground_bevelheight = 3 ;
var $titlebkg_fillstyle=TITLEBKG_FILLSTYLE_SOLID;
var $titlebkg_scolor1='black',$titlebkg_scolor2='white';
var $framebevel = false, $framebeveldepth = 2 ;
var $framebevelborder = false, $framebevelbordercolor='black';
var $framebevelcolor1='white@0.4', $framebevelcolor2='black@0.4';
var $background_image_mix=100;
var $background_cflag = '';
var $background_cflag_type = BGIMG_FILLPLOT;
var $background_cflag_mix = 100;
var $iImgTrans=false,
$iImgTransHorizon = 100,$iImgTransSkewDist=150,
$iImgTransDirection = 1, $iImgTransMinSize = true,
$iImgTransFillColor='white',$iImgTransHighQ=false,
$iImgTransBorder=false,$iImgTransHorizonPos=0.5;
var $iYAxisDeltaPos=50;
var $iIconDepth=DEPTH_BACK;
var $iAxisLblBgType = 0,
$iXAxisLblBgFillColor = 'lightgray', $iXAxisLblBgColor = 'black',
$iYAxisLblBgFillColor = 'lightgray', $iYAxisLblBgColor = 'black';
var $iTables=NULL;
var $legend;
 
//---------------
// CONSTRUCTOR
 
// aWIdth Width in pixels of image
// aHeight Height in pixels of image
// aCachedName Name for image file in cache directory
// aTimeOut Timeout in minutes for image in cache
// aInline If true the image is streamed back in the call to Stroke()
// If false the image is just created in the cache
function Graph($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) {
GLOBAL $gJpgBrandTiming;
// If timing is used create a new timing object
if( $gJpgBrandTiming ) {
global $tim;
$tim = new JpgTimer();
$tim->Push();
}
 
if( !is_numeric($aWidth) || !is_numeric($aHeight) ) {
JpGraphError::RaiseL(25008);//('Image width/height argument in Graph::Graph() must be numeric');
}
// Automatically generate the image file name based on the name of the script that
// generates the graph
if( $aCachedName=="auto" )
$aCachedName=GenImgName();
// Should the image be streamed back to the browser or only to the cache?
$this->inline=$aInline;
$this->img = new RotImage($aWidth,$aHeight);
 
$this->cache = new ImgStreamCache($this->img);
$this->cache->SetTimeOut($aTimeOut);
 
$this->title = new Text();
$this->title->ParagraphAlign('center');
$this->title->SetFont(FF_FONT2,FS_BOLD);
$this->title->SetMargin(3);
$this->title->SetAlign('center');
 
$this->subtitle = new Text();
$this->subtitle->ParagraphAlign('center');
$this->subtitle->SetMargin(2);
$this->subtitle->SetAlign('center');
 
$this->subsubtitle = new Text();
$this->subsubtitle->ParagraphAlign('center');
$this->subsubtitle->SetMargin(2);
$this->subsubtitle->SetAlign('center');
 
$this->legend = new Legend();
$this->footer = new Footer();
 
// Window doesn't like '?' in the file name so replace it with an '_'
$aCachedName = str_replace("?","_",$aCachedName);
 
// If the cached version exist just read it directly from the
// cache, stream it back to browser and exit
if( $aCachedName!="" && READ_CACHE && $aInline )
if( $this->cache->GetAndStream($aCachedName) ) {
exit();
}
$this->cache_name = $aCachedName;
$this->SetTickDensity(); // Normal density
 
$this->tabtitle = new GraphTabTitle();
}
//---------------
// PUBLIC METHODS
// Enable final image perspective transformation
function Set3DPerspective($aDir=1,$aHorizon=100,$aSkewDist=120,$aQuality=false,$aFillColor='#FFFFFF',$aBorder=false,$aMinSize=true,$aHorizonPos=0.5) {
$this->iImgTrans = true;
$this->iImgTransHorizon = $aHorizon;
$this->iImgTransSkewDist= $aSkewDist;
$this->iImgTransDirection = $aDir;
$this->iImgTransMinSize = $aMinSize;
$this->iImgTransFillColor=$aFillColor;
$this->iImgTransHighQ=$aQuality;
$this->iImgTransBorder=$aBorder;
$this->iImgTransHorizonPos=$aHorizonPos;
}
 
// Set Image format and optional quality
function SetImgFormat($aFormat,$aQuality=75) {
$this->img->SetImgFormat($aFormat,$aQuality);
}
 
// Should the grid be in front or back of the plot?
function SetGridDepth($aDepth) {
$this->grid_depth=$aDepth;
}
 
function SetIconDepth($aDepth) {
$this->iIconDepth=$aDepth;
}
// Specify graph angle 0-360 degrees.
function SetAngle($aAngle) {
$this->img->SetAngle($aAngle);
}
 
function SetAlphaBlending($aFlg=true) {
$this->img->SetAlphaBlending($aFlg);
}
 
// Shortcut to image margin
function SetMargin($lm,$rm,$tm,$bm) {
$this->img->SetMargin($lm,$rm,$tm,$bm);
}
 
function SetY2OrderBack($aBack=true) {
$this->y2orderback = $aBack;
}
 
// Rotate the graph 90 degrees and set the margin
// when we have done a 90 degree rotation
function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) {
$lm = $lm ==0 ? floor(0.2 * $this->img->width) : $lm ;
$rm = $rm ==0 ? floor(0.1 * $this->img->width) : $rm ;
$tm = $tm ==0 ? floor(0.2 * $this->img->height) : $tm ;
$bm = $bm ==0 ? floor(0.1 * $this->img->height) : $bm ;
 
$adj = ($this->img->height - $this->img->width)/2;
$this->img->SetMargin($tm-$adj,$bm-$adj,$rm+$adj,$lm+$adj);
$this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2));
$this->SetAngle(90);
if( empty($this->yaxis) || empty($this->xaxis) ) {
JpgraphError::RaiseL(25009);//('You must specify what scale to use with a call to Graph::SetScale()');
}
$this->xaxis->SetLabelAlign('right','center');
$this->yaxis->SetLabelAlign('center','bottom');
}
function SetClipping($aFlg=true) {
$this->iDoClipping = $aFlg ;
}
 
// Add a plot object to the graph
function Add(&$aPlot) {
if( $aPlot == null )
JpGraphError::RaiseL(25010);//("Graph::Add() You tried to add a null plot to the graph.");
if( is_array($aPlot) && count($aPlot) > 0 )
$cl = $aPlot[0];
else
$cl = $aPlot;
 
if( is_a($cl,'Text') )
$this->AddText($aPlot);
elseif( is_a($cl,'PlotLine') )
$this->AddLine($aPlot);
elseif( is_a($cl,'PlotBand') )
$this->AddBand($aPlot);
elseif( is_a($cl,'IconPlot') )
$this->AddIcon($aPlot);
elseif( is_a($cl,'GTextTable') )
$this->AddTable($aPlot);
else
$this->plots[] = &$aPlot;
}
 
 
function AddTable(&$aTable) {
if( is_array($aTable) ) {
for($i=0; $i < count($aTable); ++$i )
$this->iTables[]=&$aTable[$i];
}
else {
$this->iTables[] = &$aTable ;
}
}
 
function AddIcon(&$aIcon) {
if( is_array($aIcon) ) {
for($i=0; $i < count($aIcon); ++$i )
$this->iIcons[]=&$aIcon[$i];
}
else {
$this->iIcons[] = &$aIcon ;
}
}
 
// Add plot to second Y-scale
function AddY2(&$aPlot) {
if( $aPlot == null )
JpGraphError::RaiseL(25011);//("Graph::AddY2() You tried to add a null plot to the graph.");
 
if( is_array($aPlot) && count($aPlot) > 0 )
$cl = $aPlot[0];
else
$cl = $aPlot;
 
if( is_a($cl,'Text') )
$this->AddText($aPlot,true);
elseif( is_a($cl,'PlotLine') )
$this->AddLine($aPlot,true);
elseif( is_a($cl,'PlotBand') )
$this->AddBand($aPlot,true);
else
$this->y2plots[] = &$aPlot;
}
 
// Add plot to second Y-scale
function AddY($aN,&$aPlot) {
 
if( $aPlot == null )
JpGraphError::RaiseL(25012);//("Graph::AddYN() You tried to add a null plot to the graph.");
 
if( is_array($aPlot) && count($aPlot) > 0 )
$cl = $aPlot[0];
else
$cl = $aPlot;
 
if( is_a($cl,'Text') || is_a($cl,'PlotLine') || is_a($cl,'PlotBand') )
JpGraph::RaiseL(25013);//('You can only add standard plots to multiple Y-axis');
else
$this->ynplots[$aN][] = &$aPlot;
}
// Add text object to the graph
function AddText(&$aTxt,$aToY2=false) {
if( $aTxt == null )
JpGraphError::RaiseL(25014);//("Graph::AddText() You tried to add a null text to the graph.");
if( $aToY2 ) {
if( is_array($aTxt) ) {
for($i=0; $i < count($aTxt); ++$i )
$this->y2texts[]=&$aTxt[$i];
}
else
$this->y2texts[] = &$aTxt;
}
else {
if( is_array($aTxt) ) {
for($i=0; $i < count($aTxt); ++$i )
$this->texts[]=&$aTxt[$i];
}
else
$this->texts[] = &$aTxt;
}
}
// Add a line object (class PlotLine) to the graph
function AddLine(&$aLine,$aToY2=false) {
if( $aLine == null )
JpGraphError::RaiseL(25015);//("Graph::AddLine() You tried to add a null line to the graph.");
 
if( $aToY2 ) {
if( is_array($aLine) ) {
for($i=0; $i < count($aLine); ++$i )
$this->y2lines[]=&$aLine[$i];
}
else
$this->y2lines[] = &$aLine;
}
else {
if( is_array($aLine) ) {
for($i=0; $i < count($aLine); ++$i )
$this->lines[]=&$aLine[$i];
}
else
$this->lines[] = &$aLine;
}
}
 
// Add vertical or horizontal band
function AddBand(&$aBand,$aToY2=false) {
if( $aBand == null )
JpGraphError::RaiseL(25016);//(" Graph::AddBand() You tried to add a null band to the graph.");
 
if( $aToY2 ) {
if( is_array($aBand) ) {
for($i=0; $i < count($aBand); ++$i )
$this->y2bands[] = &$aBand[$i];
}
else
$this->y2bands[] = &$aBand;
}
else {
if( is_array($aBand) ) {
for($i=0; $i < count($aBand); ++$i )
$this->bands[] = &$aBand[$i];
}
else
$this->bands[] = &$aBand;
}
}
 
function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2,$aStyle=BGRAD_FRAME) {
$this->bkg_gradtype=$aGradType;
$this->bkg_gradstyle=$aStyle;
$this->bkg_gradfrom = $aFrom;
$this->bkg_gradto = $aTo;
}
// Set a country flag in the background
function SetBackgroundCFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) {
$this->background_cflag = $aName;
$this->background_cflag_type = $aBgType;
$this->background_cflag_mix = $aMix;
}
 
// Alias for the above method
function SetBackgroundCountryFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) {
$this->background_cflag = $aName;
$this->background_cflag_type = $aBgType;
$this->background_cflag_mix = $aMix;
}
 
 
// Specify a background image
function SetBackgroundImage($aFileName,$aBgType=BGIMG_FILLPLOT,$aImgFormat="auto") {
 
// Get extension to determine image type
if( $aImgFormat == "auto" ) {
$e = explode('.',$aFileName);
if( !$e ) {
JpGraphError::RaiseL(25018,$aFileName);//('Incorrect file name for Graph::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::RaiseL(25019,$aImgFormat);//('Unknown file extension ($aImgFormat) in Graph::SetBackgroundImage() for filename: '.$aFileName);
}
}
 
$this->background_image = $aFileName;
$this->background_image_type=$aBgType;
$this->background_image_format=$aImgFormat;
}
 
function SetBackgroundImageMix($aMix) {
$this->background_image_mix = $aMix ;
}
// Specify axis style (boxed or single)
function SetAxisStyle($aStyle) {
$this->iAxisStyle = $aStyle ;
}
// Set a frame around the plot area
function SetBox($aDrawPlotFrame=true,$aPlotFrameColor=array(0,0,0),$aPlotFrameWeight=1) {
$this->boxed = $aDrawPlotFrame;
$this->box_weight = $aPlotFrameWeight;
$this->box_color = $aPlotFrameColor;
}
// Specify color for the plotarea (not the margins)
function SetColor($aColor) {
$this->plotarea_color=$aColor;
}
// Specify color for the margins (all areas outside the plotarea)
function SetMarginColor($aColor) {
$this->margin_color=$aColor;
}
// Set a frame around the entire image
function SetFrame($aDrawImgFrame=true,$aImgFrameColor=array(0,0,0),$aImgFrameWeight=1) {
$this->doframe = $aDrawImgFrame;
$this->frame_color = $aImgFrameColor;
$this->frame_weight = $aImgFrameWeight;
}
 
function SetFrameBevel($aDepth=3,$aBorder=false,$aBorderColor='black',$aColor1='white@0.4',$aColor2='darkgray@0.4',$aFlg=true) {
$this->framebevel = $aFlg ;
$this->framebeveldepth = $aDepth ;
$this->framebevelborder = $aBorder ;
$this->framebevelbordercolor = $aBorderColor ;
$this->framebevelcolor1 = $aColor1 ;
$this->framebevelcolor2 = $aColor2 ;
 
$this->doshadow = false ;
}
 
// Set the shadow around the whole image
function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor=array(102,102,102)) {
$this->doshadow = $aShowShadow;
$this->shadow_color = $aShadowColor;
$this->shadow_width = $aShadowWidth;
$this->footer->iBottomMargin += $aShadowWidth;
$this->footer->iRightMargin += $aShadowWidth;
}
 
// Specify x,y scale. Note that if you manually specify the scale
// you must also specify the tick distance with a call to Ticks::Set()
function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) {
$this->axtype = $aAxisType;
 
if( $aYMax < $aYMin || $aXMax < $aXMin )
JpGraphError::RaiseL(25020);//('Graph::SetScale(): Specified Max value must be larger than the specified Min value.');
 
$yt=substr($aAxisType,-3,3);
if( $yt=="lin" )
$this->yscale = new LinearScale($aYMin,$aYMax);
elseif( $yt == "int" ) {
$this->yscale = new LinearScale($aYMin,$aYMax);
$this->yscale->SetIntScale();
}
elseif( $yt=="log" )
$this->yscale = new LogScale($aYMin,$aYMax);
else
JpGraphError::RaiseL(25021,$aAxisType);//("Unknown scale specification for Y-scale. ($aAxisType)");
$xt=substr($aAxisType,0,3);
if( $xt == "lin" || $xt == "tex" ) {
$this->xscale = new LinearScale($aXMin,$aXMax,"x");
$this->xscale->textscale = ($xt == "tex");
}
elseif( $xt == "int" ) {
$this->xscale = new LinearScale($aXMin,$aXMax,"x");
$this->xscale->SetIntScale();
}
elseif( $xt == "dat" ) {
$this->xscale = new DateScale($aXMin,$aXMax,"x");
}
elseif( $xt == "log" )
$this->xscale = new LogScale($aXMin,$aXMax,"x");
else
JpGraphError::RaiseL(25022,$aAxisType);//(" Unknown scale specification for X-scale. ($aAxisType)");
 
$this->xaxis = new Axis($this->img,$this->xscale);
$this->yaxis = new Axis($this->img,$this->yscale);
$this->xgrid = new Grid($this->xaxis);
$this->ygrid = new Grid($this->yaxis);
$this->ygrid->Show();
}
// Specify secondary Y scale
function SetY2Scale($aAxisType="lin",$aY2Min=1,$aY2Max=1) {
if( $aAxisType=="lin" )
$this->y2scale = new LinearScale($aY2Min,$aY2Max);
elseif( $aAxisType == "int" ) {
$this->y2scale = new LinearScale($aY2Min,$aY2Max);
$this->y2scale->SetIntScale();
}
elseif( $aAxisType=="log" ) {
$this->y2scale = new LogScale($aY2Min,$aY2Max);
}
else JpGraphError::RaiseL(25023,$aAxisType);//("JpGraph: Unsupported Y2 axis type: $aAxisType\nMust be one of (lin,log,int)");
$this->y2axis = new Axis($this->img,$this->y2scale);
$this->y2axis->scale->ticks->SetDirection(SIDE_LEFT);
$this->y2axis->SetLabelSide(SIDE_RIGHT);
$this->y2axis->SetPos('max');
$this->y2axis->SetTitleSide(SIDE_RIGHT);
// Deafult position is the max x-value
$this->y2grid = new Grid($this->y2axis);
}
 
// Set the delta position (in pixels) between the multiple Y-axis
function SetYDeltaDist($aDist) {
$this->iYAxisDeltaPos = $aDist;
}
// Specify secondary Y scale
function SetYScale($aN,$aAxisType="lin",$aYMin=1,$aYMax=1) {
 
if( $aAxisType=="lin" )
$this->ynscale[$aN] = new LinearScale($aYMin,$aYMax);
elseif( $aAxisType == "int" ) {
$this->ynscale[$aN] = new LinearScale($aYMin,$aYMax);
$this->ynscale[$aN]->SetIntScale();
}
elseif( $aAxisType=="log" ) {
$this->ynscale[$aN] = new LogScale($aYMin,$aYMax);
}
else JpGraphError::RaiseL(25024,$aAxisType);//("JpGraph: Unsupported Y axis type: $aAxisType\nMust be one of (lin,log,int)");
$this->ynaxis[$aN] = new Axis($this->img,$this->ynscale[$aN]);
$this->ynaxis[$aN]->scale->ticks->SetDirection(SIDE_LEFT);
$this->ynaxis[$aN]->SetLabelSide(SIDE_RIGHT);
}
 
// Specify density of ticks when autoscaling 'normal', 'dense', 'sparse', 'verysparse'
// The dividing factor have been determined heuristically according to my aesthetic
// sense (or lack off) y.m.m.v !
function SetTickDensity($aYDensity=TICKD_NORMAL,$aXDensity=TICKD_NORMAL) {
$this->xtick_factor=30;
$this->ytick_factor=25;
switch( $aYDensity ) {
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=100;
break;
default:
JpGraphError::RaiseL(25025,$densy);//("JpGraph: Unsupported Tick density: $densy");
}
switch( $aXDensity ) {
case TICKD_DENSE:
$this->xtick_factor=15;
break;
case TICKD_NORMAL:
$this->xtick_factor=30;
break;
case TICKD_SPARSE:
$this->xtick_factor=45;
break;
case TICKD_VERYSPARSE:
$this->xtick_factor=60;
break;
default:
JpGraphError::RaiseL(25025,$densx);//("JpGraph: Unsupported Tick density: $densx");
}
}
 
// Get a string of all image map areas
function GetCSIMareas() {
if( !$this->iHasStroked )
$this->Stroke(_CSIM_SPECIALFILE);
 
$csim = $this->title->GetCSIMAreas();
$csim .= $this->subtitle->GetCSIMAreas();
$csim .= $this->subsubtitle->GetCSIMAreas();
$csim .= $this->legend->GetCSIMAreas();
 
if( $this->y2axis != NULL ) {
$csim .= $this->y2axis->title->GetCSIMAreas();
}
 
if( $this->texts != null ) {
$n = count($this->texts);
for($i=0; $i < $n; ++$i ) {
$csim .= $this->texts[$i]->GetCSIMAreas();
}
}
 
if( $this->y2texts != null && $this->y2scale != null ) {
$n = count($this->y2texts);
for($i=0; $i < $n; ++$i ) {
$csim .= $this->y2texts[$i]->GetCSIMAreas();
}
}
 
if( $this->yaxis != null && $this->xaxis != null ) {
$csim .= $this->yaxis->title->GetCSIMAreas();
$csim .= $this->xaxis->title->GetCSIMAreas();
}
 
$n = count($this->plots);
for( $i=0; $i < $n; ++$i )
$csim .= $this->plots[$i]->GetCSIMareas();
 
$n = count($this->y2plots);
for( $i=0; $i < $n; ++$i )
$csim .= $this->y2plots[$i]->GetCSIMareas();
 
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
$m = count($this->ynplots[$i]);
for($j=0; $j < $m; ++$j ) {
$csim .= $this->ynplots[$i][$j]->GetCSIMareas();
}
}
 
$n = count($this->iTables);
for( $i=0; $i < $n; ++$i ) {
$csim .= $this->iTables[$i]->GetCSIMareas();
}
 
return $csim;
}
// Get a complete <MAP>..</MAP> tag for the final image map
function GetHTMLImageMap($aMapName) {
$im = "<map name=\"$aMapName\" id=\"$aMapName\" >\n";
$im .= $this->GetCSIMareas();
$im .= "</map>";
return $im;
}
 
function CheckCSIMCache($aCacheName,$aTimeOut=60) {
global $_SERVER;
 
if( $aCacheName=='auto' )
$aCacheName=basename($_SERVER['PHP_SELF']);
 
$urlarg = $this->GetURLArguments();
$this->csimcachename = CSIMCACHE_DIR.$aCacheName.$urlarg;
$this->csimcachetimeout = $aTimeOut;
 
// First determine if we need to check for a cached version
// This differs from the standard cache in the sense that the
// image and CSIM map HTML file is written relative to the directory
// the script executes in and not the specified cache directory.
// The reason for this is that the cache directory is not necessarily
// accessible from the HTTP server.
if( $this->csimcachename != '' ) {
$dir = dirname($this->csimcachename);
$base = basename($this->csimcachename);
$base = strtok($base,'.');
$suffix = strtok('.');
$basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html';
$baseimg = $dir.'/'.$base.'?'.$urlarg.'.'.$this->img->img_format;
 
$timedout=false;
// Does it exist at all ?
if( file_exists($basecsim) && file_exists($baseimg) ) {
// Check that it hasn't timed out
$diff=time()-filemtime($basecsim);
if( $this->csimcachetimeout>0 && ($diff > $this->csimcachetimeout*60) ) {
$timedout=true;
@unlink($basecsim);
@unlink($baseimg);
}
else {
if ($fh = @fopen($basecsim, "r")) {
fpassthru($fh);
return true;
}
else
JpGraphError::RaiseL(25027,$basecsim);//(" Can't open cached CSIM \"$basecsim\" for reading.");
}
}
}
return false;
}
 
// Build the argument string to be used with the csim images
function GetURLArguments() {
// This is a JPGRAPH internal defined that prevents
// us from recursively coming here again
$urlarg = _CSIM_DISPLAY.'=1';
 
// Now reconstruct any user URL argument
reset($_GET);
while( list($key,$value) = each($_GET) ) {
if( is_array($value) ) {
foreach ( $value as $k => $v ) {
$urlarg .= '&amp;'.$key.'%5B'.$k.'%5D='.urlencode($v);
}
}
else {
$urlarg .= '&amp;'.$key.'='.urlencode($value);
}
}
 
// It's not ideal to convert POST argument to GET arguments
// but there is little else we can do. One idea for the
// future might be recreate the POST header in case.
reset($_POST);
while( list($key,$value) = each($_POST) ) {
if( is_array($value) ) {
foreach ( $value as $k => $v ) {
$urlarg .= '&amp;'.$key.'%5B'.$k.'%5D='.urlencode($v);
}
}
else {
$urlarg .= '&amp;'.$key.'='.urlencode($value);
}
}
 
return $urlarg;
}
 
function SetCSIMImgAlt($aAlt) {
$this->iCSIMImgAlt = $aAlt;
}
 
function StrokeCSIM($aScriptName='auto',$aCSIMName='',$aBorder=0) {
if( $aCSIMName=='' ) {
// create a random map name
srand ((double) microtime() * 1000000);
$r = rand(0,100000);
$aCSIMName='__mapname'.$r.'__';
}
 
if( $aScriptName=='auto' )
$aScriptName=basename($_SERVER['PHP_SELF']);
 
$urlarg = $this->GetURLArguments();
 
if( empty($_GET[_CSIM_DISPLAY]) ) {
// First determine if we need to check for a cached version
// This differs from the standard cache in the sense that the
// image and CSIM map HTML file is written relative to the directory
// the script executes in and not the specified cache directory.
// The reason for this is that the cache directory is not necessarily
// accessible from the HTTP server.
if( $this->csimcachename != '' ) {
$dir = dirname($this->csimcachename);
$base = basename($this->csimcachename);
$base = strtok($base,'.');
$suffix = strtok('.');
$basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html';
$baseimg = $base.'?'.$urlarg.'.'.$this->img->img_format;
 
// Check that apache can write to directory specified
 
if( file_exists($dir) && !is_writeable($dir) ) {
JpgraphError::RaiseL(25028,$dir);//('Apache/PHP does not have permission to write to the CSIM cache directory ('.$dir.'). Check permissions.');
}
// Make sure directory exists
$this->cache->MakeDirs($dir);
 
// Write the image file
$this->Stroke(CSIMCACHE_DIR.$baseimg);
 
// Construct wrapper HTML and write to file and send it back to browser
 
// In the src URL we must replace the '?' with its encoding to prevent the arguments
// to be converted to real arguments.
$tmp = str_replace('?','%3f',$baseimg);
$htmlwrap = $this->GetHTMLImageMap($aCSIMName)."\n".
'<img src="'.CSIMCACHE_HTTP_DIR.$tmp.'" ismap="ismap" usemap="#'.$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n";
 
if($fh = @fopen($basecsim,'w') ) {
fwrite($fh,$htmlwrap);
fclose($fh);
echo $htmlwrap;
}
else
JpGraphError::RaiseL(25029,$basecsim);//(" Can't write CSIM \"$basecsim\" for writing. Check free space and permissions.");
}
else {
 
if( $aScriptName=='' ) {
JpGraphError::RaiseL(25030);//('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().');
}
echo $this->GetHTMLImageMap($aCSIMName);
echo "<img src=\"".$aScriptName.'?'.$urlarg."\" ismap=\"ismap\" usemap=\"#".$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n";
}
}
else {
$this->Stroke();
}
}
 
function GetTextsYMinMax($aY2=false) {
if( $aY2 )
$txts = $this->y2texts;
else
$txts = $this->texts;
$n = count($txts);
$min=null;
$max=null;
for( $i=0; $i < $n; ++$i ) {
if( $txts[$i]->iScalePosY !== null &&
$txts[$i]->iScalePosX !== null ) {
if( $min === null ) {
$min = $max = $txts[$i]->iScalePosY ;
}
else {
$min = min($min,$txts[$i]->iScalePosY);
$max = max($max,$txts[$i]->iScalePosY);
}
}
}
if( $min !== null ) {
return array($min,$max);
}
else
return null;
}
 
function GetTextsXMinMax($aY2=false) {
if( $aY2 )
$txts = $this->y2texts;
else
$txts = $this->texts;
$n = count($txts);
$min=null;
$max=null;
for( $i=0; $i < $n; ++$i ) {
if( $txts[$i]->iScalePosY !== null &&
$txts[$i]->iScalePosX !== null ) {
if( $min === null ) {
$min = $max = $txts[$i]->iScalePosX ;
}
else {
$min = min($min,$txts[$i]->iScalePosX);
$max = max($max,$txts[$i]->iScalePosX);
}
}
}
if( $min !== null ) {
return array($min,$max);
}
else
return null;
}
 
function GetXMinMax() {
list($min,$ymin) = $this->plots[0]->Min();
list($max,$ymax) = $this->plots[0]->Max();
foreach( $this->plots as $p ) {
list($xmin,$ymin) = $p->Min();
list($xmax,$ymax) = $p->Max();
$min = Min($xmin,$min);
$max = Max($xmax,$max);
}
 
if( $this->y2axis != null ) {
foreach( $this->y2plots as $p ) {
list($xmin,$ymin) = $p->Min();
list($xmax,$ymax) = $p->Max();
$min = Min($xmin,$min);
$max = Max($xmax,$max);
}
}
 
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
if( $this->ynaxis[$i] != null) {
foreach( $this->ynplots[$i] as $p ) {
list($xmin,$ymin) = $p->Min();
list($xmax,$ymax) = $p->Max();
$min = Min($xmin,$min);
$max = Max($xmax,$max);
}
}
}
 
return array($min,$max);
}
 
function AdjustMarginsForTitles() {
$totrequired =
($this->title->t != '' ?
$this->title->GetTextHeight($this->img) + $this->title->margin + 5 : 0 ) +
($this->subtitle->t != '' ?
$this->subtitle->GetTextHeight($this->img) + $this->subtitle->margin + 5 : 0 ) +
($this->subsubtitle->t != '' ?
$this->subsubtitle->GetTextHeight($this->img) + $this->subsubtitle->margin + 5 : 0 ) ;
 
$btotrequired = 0;
if($this->xaxis != null && !$this->xaxis->hide && !$this->xaxis->hide_labels ) {
// Minimum bottom margin
if( $this->xaxis->title->t != '' ) {
if( $this->img->a == 90 )
$btotrequired = $this->yaxis->title->GetTextHeight($this->img) + 5 ;
else
$btotrequired = $this->xaxis->title->GetTextHeight($this->img) + 5 ;
}
else
$btotrequired = 0;
if( $this->img->a == 90 ) {
$this->img->SetFont($this->yaxis->font_family,$this->yaxis->font_style,
$this->yaxis->font_size);
$lh = $this->img->GetTextHeight('Mg',$this->yaxis->label_angle);
}
else {
$this->img->SetFont($this->xaxis->font_family,$this->xaxis->font_style,
$this->xaxis->font_size);
$lh = $this->img->GetTextHeight('Mg',$this->xaxis->label_angle);
}
$btotrequired += $lh + 5;
}
 
if( $this->img->a == 90 ) {
// DO Nothing. It gets too messy to do this properly for 90 deg...
}
else{
if( $this->img->top_margin < $totrequired ) {
$this->SetMargin($this->img->left_margin,$this->img->right_margin,
$totrequired,$this->img->bottom_margin);
}
if( $this->img->bottom_margin < $btotrequired ) {
$this->SetMargin($this->img->left_margin,$this->img->right_margin,
$this->img->top_margin,$btotrequired);
}
}
}
 
// Stroke the graph
// $aStrokeFileName If != "" the image will be written to this file and NOT
// streamed back to the browser
function Stroke($aStrokeFileName="") {
 
// Fist make a sanity check that user has specified a scale
if( empty($this->yscale) ) {
JpGraphError::RaiseL(25031);//('You must specify what scale to use with a call to Graph::SetScale().');
}
 
// Start by adjusting the margin so that potential titles will fit.
$this->AdjustMarginsForTitles();
 
// Setup scale constants
if( $this->yscale ) $this->yscale->InitConstants($this->img);
if( $this->xscale ) $this->xscale->InitConstants($this->img);
if( $this->y2scale ) $this->y2scale->InitConstants($this->img);
$n=count($this->ynscale);
for($i=0; $i < $n; ++$i) {
if( $this->ynscale[$i] ) $this->ynscale[$i]->InitConstants($this->img);
}
 
// 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;
 
// Do any pre-stroke adjustment that is needed by the different plot types
// (i.e bar plots want's to add an offset to the x-labels etc)
for($i=0; $i < count($this->plots) ; ++$i ) {
$this->plots[$i]->PreStrokeAdjust($this);
$this->plots[$i]->DoLegend($this);
}
// Any plots on the second Y scale?
if( $this->y2scale != null ) {
for($i=0; $i<count($this->y2plots) ; ++$i ) {
$this->y2plots[$i]->PreStrokeAdjust($this);
$this->y2plots[$i]->DoLegend($this);
}
}
 
// Any plots on the extra Y axises?
$n = count($this->ynaxis);
for($i=0; $i<$n ; ++$i ) {
if( $this->ynplots == null || $this->ynplots[$i] == null) {
JpGraphError::RaiseL(25032,$i);//("No plots for Y-axis nbr:$i");
}
$m = count($this->ynplots[$i]);
for($j=0; $j < $m; ++$j ) {
$this->ynplots[$i][$j]->PreStrokeAdjust($this);
$this->ynplots[$i][$j]->DoLegend($this);
}
}
 
// Bail out if any of the Y-axis not been specified and
// has no plots. (This means it is impossible to do autoscaling and
// no other scale was given so we can't possible draw anything). If you use manual
// scaling you also have to supply the tick steps as well.
if( (!$this->yscale->IsSpecified() && count($this->plots)==0) ||
($this->y2scale!=null && !$this->y2scale->IsSpecified() && count($this->y2plots)==0) ) {
//$e = "n=".count($this->y2plots)."\n";
// $e = "Can't draw unspecified Y-scale.<br>\nYou have either:<br>\n";
// $e .= "1. Specified an Y axis for autoscaling but have not supplied any plots<br>\n";
// $e .= "2. Specified a scale manually but have forgot to specify the tick steps";
JpGraphError::RaiseL(25026);
}
// Bail out if no plots and no specified X-scale
if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) )
JpGraphError::RaiseL(25034);//("<strong>JpGraph: Can't draw unspecified X-scale.</strong><br>No plots.<br>");
 
//Check if we should autoscale y-axis
if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) {
list($min,$max) = $this->GetPlotsYMinMax($this->plots);
$lres = $this->GetLinesYMinMax($this->lines);
if( is_array($lres) ) {
list($linmin,$linmax) = $lres ;
$min = min($min,$linmin);
$max = max($max,$linmax);
}
$tres = $this->GetTextsYMinMax();
if( is_array($tres) ) {
list($tmin,$tmax) = $tres ;
$min = min($min,$tmin);
$max = max($max,$tmax);
}
$this->yscale->AutoScale($this->img,$min,$max,
$this->img->plotheight/$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->img->plotheight/$this->ytick_factor,
$this->yscale->auto_ticks);
}
 
if( $this->y2scale != null) {
if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) {
list($min,$max) = $this->GetPlotsYMinMax($this->y2plots);
$lres = $this->GetLinesYMinMax($this->y2lines);
if( is_array($lres) ) {
list($linmin,$linmax) = $lres ;
$min = min($min,$linmin);
$max = max($max,$linmax);
}
$tres = $this->GetTextsYMinMax(true);
if( is_array($tres) ) {
list($tmin,$tmax) = $tres ;
$min = min($min,$tmin);
$max = max($max,$tmax);
}
$this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor);
}
elseif( $this->y2scale->IsSpecified() &&
( $this->y2scale->auto_ticks || !$this->y2scale->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->y2scale->scale[0];
$max = $this->y2scale->scale[1];
$this->y2scale->AutoScale($this->img,$min,$max,
$this->img->plotheight/$this->ytick_factor,
$this->y2scale->auto_ticks);
}
}
 
//
// Autoscale the multiple Y-axis
//
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
if( $this->ynscale[$i] != null) {
if( !$this->ynscale[$i]->IsSpecified() && count($this->ynplots[$i])>0 ) {
list($min,$max) = $this->GetPlotsYMinMax($this->ynplots[$i]);
$this->ynscale[$i]->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor);
}
elseif( $this->ynscale[$i]->IsSpecified() &&
( $this->ynscale[$i]->auto_ticks || !$this->ynscale[$i]->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->ynscale[$i]->scale[0];
$max = $this->ynscale[$i]->scale[1];
$this->ynscale[$i]->AutoScale($this->img,$min,$max,
$this->img->plotheight/$this->ytick_factor,
$this->ynscale[$i]->auto_ticks);
}
}
}
 
//Check if we should autoscale x-axis
if( !$this->xscale->IsSpecified() ) {
if( substr($this->axtype,0,4) == "text" ) {
$max=0;
$n = count($this->plots);
for($i=0; $i < $n; ++$i ) {
$p = $this->plots[$i];
// We need some unfortunate sub class knowledge here in order
// to increase number of data points in case it is a line plot
// which has the barcenter set. If not it could mean that the
// last point of the data is outside the scale since the barcenter
// settings means that we will shift the entire plot half a tick step
// to the right in oder to align with the center of the bars.
if( is_a($p,'BarPlot') || empty($p->barcenter)) {
$max=max($max,$p->numpoints-1);
}
else {
$max=max($max,$p->numpoints);
}
}
$min=0;
if( $this->y2axis != null ) {
foreach( $this->y2plots as $p ) {
$max=max($max,$p->numpoints-1);
}
}
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
if( $this->ynaxis[$i] != null) {
foreach( $this->ynplots[$i] as $p ) {
$max=max($max,$p->numpoints-1);
}
}
}
$this->xscale->Update($this->img,$min,$max);
$this->xscale->ticks->Set($this->xaxis->tick_step,1);
$this->xscale->ticks->SupressMinorTickMarks();
}
else {
list($min,$max) = $this->GetXMinMax();
 
$lres = $this->GetLinesXMinMax($this->lines);
if( $lres ) {
list($linmin,$linmax) = $lres ;
$min = min($min,$linmin);
$max = max($max,$linmax);
}
$lres = $this->GetLinesXMinMax($this->y2lines);
if( $lres ) {
list($linmin,$linmax) = $lres ;
$min = min($min,$linmin);
$max = max($max,$linmax);
}
 
$tres = $this->GetTextsXMinMax();
if( $tres ) {
list($tmin,$tmax) = $tres ;
$min = min($min,$tmin);
$max = max($max,$tmax);
}
 
$tres = $this->GetTextsXMinMax(true);
if( $tres ) {
list($tmin,$tmax) = $tres ;
$min = min($min,$tmin);
$max = max($max,$tmax);
}
 
$this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor));
}
//Adjust position of y-axis and y2-axis to minimum/maximum of x-scale
if( !is_numeric($this->yaxis->pos) && !is_string($this->yaxis->pos) )
$this->yaxis->SetPos($this->xscale->GetMinVal());
if( $this->y2axis != null ) {
if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) )
$this->y2axis->SetPos($this->xscale->GetMaxVal());
$this->y2axis->SetTitleSide(SIDE_RIGHT);
}
 
$n = count($this->ynaxis);
$nY2adj = $this->y2axis != null ? $this->iYAxisDeltaPos : 0;
for( $i=0; $i < $n; ++$i ) {
if( $this->ynaxis[$i] != null ) {
if( !is_numeric($this->ynaxis[$i]->pos) && !is_string($this->ynaxis[$i]->pos) ) {
$this->ynaxis[$i]->SetPos($this->xscale->GetMaxVal());
$this->ynaxis[$i]->SetPosAbsDelta($i*$this->iYAxisDeltaPos + $nY2adj);
}
$this->ynaxis[$i]->SetTitleSide(SIDE_RIGHT);
}
}
}
elseif( $this->xscale->IsSpecified() &&
( $this->xscale->auto_ticks || !$this->xscale->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->xscale->scale[0];
$max = $this->xscale->scale[1];
 
 
$this->xscale->AutoScale($this->img,$min,$max,
$this->img->plotwidth/$this->xtick_factor,
false);
 
if( $this->y2axis != null ) {
if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) )
$this->y2axis->SetPos($this->xscale->GetMaxVal());
$this->y2axis->SetTitleSide(SIDE_RIGHT);
}
 
}
// If we have a negative values and x-axis position is at 0
// we need to supress the first and possible the last tick since
// they will be drawn on top of the y-axis (and possible y2 axis)
// The test below might seem strange the reasone being that if
// the user hasn't specified a value for position this will not
// be set until we do the stroke for the axis so as of now it
// is undefined.
// For X-text scale we ignore all this since the tick are usually
// much further in and not close to the Y-axis. Hence the test
// for 'text'
 
if( ($this->yaxis->pos==$this->xscale->GetMinVal() ||
(is_string($this->yaxis->pos) && $this->yaxis->pos=='min')) &&
!is_numeric($this->xaxis->pos) && $this->yscale->GetMinVal() < 0 &&
substr($this->axtype,0,4) != 'text' && $this->xaxis->pos!="min" ) {
 
//$this->yscale->ticks->SupressZeroLabel(false);
$this->xscale->ticks->SupressFirst();
if( $this->y2axis != null ) {
$this->xscale->ticks->SupressLast();
}
}
elseif( !is_numeric($this->yaxis->pos) && $this->yaxis->pos=='max' ) {
$this->xscale->ticks->SupressLast();
}
 
if( !$_csim ) {
$this->StrokePlotArea();
if( $this->iIconDepth == DEPTH_BACK ) {
$this->StrokeIcons();
}
}
$this->StrokeAxis(false);
 
// Stroke bands
if( $this->bands != null && !$_csim)
for($i=0; $i < count($this->bands); ++$i) {
// Stroke all bands that asks to be in the background
if( $this->bands[$i]->depth == DEPTH_BACK )
$this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale);
}
 
if( $this->y2bands != null && $this->y2scale != null && !$_csim )
for($i=0; $i < count($this->y2bands); ++$i) {
// Stroke all bands that asks to be in the foreground
if( $this->y2bands[$i]->depth == DEPTH_BACK )
$this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale);
}
 
 
if( $this->grid_depth == DEPTH_BACK && !$_csim) {
$this->ygrid->Stroke();
$this->xgrid->Stroke();
}
// Stroke Y2-axis
if( $this->y2axis != null && !$_csim) {
$this->y2axis->Stroke($this->xscale);
$this->y2grid->Stroke();
}
 
// Stroke yn-axis
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
$this->ynaxis[$i]->Stroke($this->xscale);
}
$oldoff=$this->xscale->off;
if(substr($this->axtype,0,4)=="text") {
if( $this->text_scale_abscenteroff > -1 ) {
// For a text scale the scale factor is the number of pixel per step.
// Hence we can use the scale factor as a substitute for number of pixels
// per major scale step and use that in order to adjust the offset so that
// an object of width "abscenteroff" becomes centered.
$this->xscale->off += round($this->xscale->scale_factor/2)-round($this->text_scale_abscenteroff/2);
}
else {
$this->xscale->off +=
ceil($this->xscale->scale_factor*$this->text_scale_off*$this->xscale->ticks->minor_step);
}
}
 
if( $this->iDoClipping ) {
$oldimage = $this->img->CloneCanvasH();
}
 
if( ! $this->y2orderback ) {
// Stroke all plots for Y axis
for($i=0; $i < count($this->plots); ++$i) {
$this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale);
$this->plots[$i]->StrokeMargin($this->img);
}
}
 
// Stroke all plots for Y2 axis
if( $this->y2scale != null )
for($i=0; $i< count($this->y2plots); ++$i ) {
$this->y2plots[$i]->Stroke($this->img,$this->xscale,$this->y2scale);
}
 
if( $this->y2orderback ) {
// Stroke all plots for Y1 axis
for($i=0; $i < count($this->plots); ++$i) {
$this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale);
$this->plots[$i]->StrokeMargin($this->img);
}
}
 
$n = count($this->ynaxis);
for( $i=0; $i < $n; ++$i ) {
$m = count($this->ynplots[$i]);
for( $j=0; $j < $m; ++$j ) {
$this->ynplots[$i][$j]->Stroke($this->img,$this->xscale,$this->ynscale[$i]);
$this->ynplots[$i][$j]->StrokeMargin($this->img);
}
}
 
if( $this->iIconDepth == DEPTH_FRONT) {
$this->StrokeIcons();
}
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);
}
elseif( $this->img->a == 90 ) {
$adj = ($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+1,$this->img->plotwidth);
}
else {
JpGraphError::RaiseL(25035,$this->img->a);//('You have enabled clipping. Cliping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (='.$this->img->a.' degrees) or disable clipping.');
}
$this->img->Destroy();
$this->img->SetCanvasH($oldimage);
}
 
$this->xscale->off=$oldoff;
if( $this->grid_depth == DEPTH_FRONT && !$_csim ) {
$this->ygrid->Stroke();
$this->xgrid->Stroke();
}
 
// Stroke bands
if( $this->bands!= null )
for($i=0; $i < count($this->bands); ++$i) {
// Stroke all bands that asks to be in the foreground
if( $this->bands[$i]->depth == DEPTH_FRONT )
$this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale);
}
 
if( $this->y2bands!= null && $this->y2scale != null )
for($i=0; $i < count($this->y2bands); ++$i) {
// Stroke all bands that asks to be in the foreground
if( $this->y2bands[$i]->depth == DEPTH_FRONT )
$this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale);
}
 
 
// Stroke any lines added
if( $this->lines != null ) {
for($i=0; $i < count($this->lines); ++$i) {
$this->lines[$i]->Stroke($this->img,$this->xscale,$this->yscale);
$this->lines[$i]->DoLegend($this);
}
}
 
if( $this->y2lines != null && $this->y2scale != null ) {
for($i=0; $i < count($this->y2lines); ++$i) {
$this->y2lines[$i]->Stroke($this->img,$this->xscale,$this->y2scale);
$this->y2lines[$i]->DoLegend($this);
}
}
 
// Finally draw the axis again since some plots may have nagged
// the axis in the edges.However we do no stroke the labels again
// since any user defined callback would be called twice. It also
// enhances performance.
 
if( !$_csim ) {
$this->StrokeAxis();
}
 
if( $this->y2scale != null && !$_csim )
$this->y2axis->Stroke($this->xscale,false);
if( !$_csim ) {
$this->StrokePlotBox();
}
// 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();
$this->footer->Stroke($this->img);
$this->legend->Stroke($this->img);
$this->img->SetAngle($aa);
$this->StrokeTexts();
$this->StrokeTables();
 
if( !$_csim ) {
 
$this->img->SetAngle($aa);
// Draw an outline around the image map
if(_JPG_DEBUG) {
$this->DisplayClientSideaImageMapAreas();
}
// Should we do any final image transformation
if( $this->iImgTrans ) {
if( !class_exists('ImgTrans') ) {
require_once('jpgraph_imgtrans.php');
//JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.');
}
$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);
}
}
}
 
function SetAxisLabelBackground($aType,$aXFColor='lightgray',$aXColor='black',$aYFColor='lightgray',$aYColor='black') {
$this->iAxisLblBgType = $aType;
$this->iXAxisLblBgFillColor = $aXFColor;
$this->iXAxisLblBgColor = $aXColor;
$this->iYAxisLblBgFillColor = $aYFColor;
$this->iYAxisLblBgColor = $aYColor;
}
 
//---------------
// PRIVATE METHODS
 
function StrokeAxisLabelBackground() {
// Types
// 0 = No background
// 1 = Only X-labels, length of axis
// 2 = Only Y-labels, length of axis
// 3 = As 1 but extends to width of graph
// 4 = As 2 but extends to height of graph
// 5 = Combination of 3 & 4
// 6 = Combination of 1 & 2
$t = $this->iAxisLblBgType ;
if( $t < 1 ) return;
// Stroke optional X-axis label background color
if( $t == 1 || $t == 3 || $t == 5 || $t == 6 ) {
$this->img->PushColor($this->iXAxisLblBgFillColor);
if( $t == 1 || $t == 6 ) {
$xl = $this->img->left_margin;
$yu = $this->img->height - $this->img->bottom_margin + 1;
$xr = $this->img->width - $this->img->right_margin ;
$yl = $this->img->height-1-$this->frame_weight;
}
else { // t==3 || t==5
$xl = $this->frame_weight;
$yu = $this->img->height - $this->img->bottom_margin + 1;
$xr = $this->img->width - 1 - $this->frame_weight;
$yl = $this->img->height-1-$this->frame_weight;
}
 
$this->img->FilledRectangle($xl,$yu,$xr,$yl);
$this->img->PopColor();
 
// Check if we should add the vertical lines at left and right edge
if( $this->iXAxisLblBgColor !== '' ) {
$this->img->PushColor($this->iXAxisLblBgColor);
if( $t == 1 || $t == 6 ) {
$this->img->Line($xl,$yu,$xl,$yl);
$this->img->Line($xr,$yu,$xr,$yl);
}
else {
$xl = $this->img->width - $this->img->right_margin ;
$this->img->Line($xl,$yu-1,$xr,$yu-1);
}
$this->img->PopColor();
}
}
 
if( $t == 2 || $t == 4 || $t == 5 || $t == 6 ) {
$this->img->PushColor($this->iYAxisLblBgFillColor);
if( $t == 2 || $t == 6 ) {
$xl = $this->frame_weight;
$yu = $this->frame_weight+$this->img->top_margin;
$xr = $this->img->left_margin - 1;
$yl = $this->img->height - $this->img->bottom_margin + 1;
}
else {
$xl = $this->frame_weight;
$yu = $this->frame_weight;
$xr = $this->img->left_margin - 1;
$yl = $this->img->height-1-$this->frame_weight;
}
 
$this->img->FilledRectangle($xl,$yu,$xr,$yl);
$this->img->PopColor();
 
// Check if we should add the vertical lines at left and right edge
if( $this->iXAxisLblBgColor !== '' ) {
$this->img->PushColor($this->iXAxisLblBgColor);
if( $t == 2 || $t == 6 ) {
$this->img->Line($xl,$yu-1,$xr,$yu-1);
$this->img->Line($xl,$yl-1,$xr,$yl-1);
}
else {
$this->img->Line($xr+1,$yu,$xr+1,$this->img->top_margin);
}
$this->img->PopColor();
}
 
}
}
 
function StrokeAxis($aStrokeLabels=true) {
if( $aStrokeLabels ) {
$this->StrokeAxisLabelBackground();
}
 
// Stroke axis
if( $this->iAxisStyle != AXSTYLE_SIMPLE ) {
switch( $this->iAxisStyle ) {
case AXSTYLE_BOXIN :
$toppos = SIDE_DOWN;
$bottompos = SIDE_UP;
$leftpos = SIDE_RIGHT;
$rightpos = SIDE_LEFT;
break;
case AXSTYLE_BOXOUT :
$toppos = SIDE_UP;
$bottompos = SIDE_DOWN;
$leftpos = SIDE_LEFT;
$rightpos = SIDE_RIGHT;
break;
case AXSTYLE_YBOXIN:
$toppos = -100;
$bottompos = SIDE_UP;
$leftpos = SIDE_RIGHT;
$rightpos = SIDE_LEFT;
break;
case AXSTYLE_YBOXOUT:
$toppos = -100;
$bottompos = SIDE_DOWN;
$leftpos = SIDE_LEFT;
$rightpos = SIDE_RIGHT;
break;
default:
JpGRaphError::RaiseL(25036,$this->iAxisStyle); //('Unknown AxisStyle() : '.$this->iAxisStyle);
break;
}
$this->xaxis->SetPos('min');
// By default we hide the first label so it doesn't cross the
// Y-axis in case the positon hasn't been set by the user.
// However, if we use a box we always want the first value
// displayed so we make sure it will be displayed.
$this->xscale->ticks->SupressFirst(false);
$this->xaxis->SetLabelSide(SIDE_DOWN);
$this->xaxis->scale->ticks->SetSide($bottompos);
$this->xaxis->Stroke($this->yscale);
 
if( $toppos != -100 ) {
// To avoid side effects we work on a new copy
$maxis = $this->xaxis;
$maxis->SetPos('max');
$maxis->SetLabelSide(SIDE_UP);
$maxis->SetLabelMargin(7);
$this->xaxis->scale->ticks->SetSide($toppos);
$maxis->Stroke($this->yscale);
}
 
$this->yaxis->SetPos('min');
$this->yaxis->SetLabelMargin(10);
$this->yaxis->SetLabelSide(SIDE_LEFT);
$this->yaxis->scale->ticks->SetSide($leftpos);
$this->yaxis->Stroke($this->xscale);
 
$myaxis = $this->yaxis;
$myaxis->SetPos('max');
$myaxis->SetLabelMargin(10);
$myaxis->SetLabelSide(SIDE_RIGHT);
$myaxis->title->Set('');
$myaxis->scale->ticks->SetSide($rightpos);
$myaxis->Stroke($this->xscale);
}
else {
$this->xaxis->Stroke($this->yscale,$aStrokeLabels);
$this->yaxis->Stroke($this->xscale,$aStrokeLabels);
}
}
 
 
// Private helper function for backgound image
function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') {
if( $aImgStr != '' ) {
return Image::CreateFromString($aImgStr);
}
 
// 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
 
if( $aImgFormat == '' )
$imgtag = $ext;
else
$imgtag = $aImgFormat;
 
$supported = imagetypes();
if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) ||
( $ext == 'gif' && !($supported & IMG_GIF) ) ||
( $ext == 'png' && !($supported & IMG_PNG) ) ||
( $ext == 'bmp' && !($supported & IMG_WBMP) ) ||
( $ext == 'xpm' && !($supported & IMG_XPM) ) ) {
JpGraphError::RaiseL(25037,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. ');
}
 
 
if( $imgtag == "jpg" || $imgtag == "jpeg")
{
$f = "imagecreatefromjpeg";
$imgtag = "jpg";
}
else
{
$f = "imagecreatefrom".$imgtag;
}
 
// Compare specified image type and file extension
if( $imgtag != $ext ) {
//$t = "Background image seems to be of different type (has different file extension) than specified imagetype. Specified: '".$aImgFormat."'File: '".$aFile."'";
JpGraphError::RaiseL(25038, $aImgFormat, $aFile);
}
 
$img = @$f($aFile);
if( !$img ) {
JpGraphError::RaiseL(25039,$aFile);//(" Can't read background image: '".$aFile."'");
}
return $img;
}
 
function StrokeBackgroundGrad() {
if( $this->bkg_gradtype < 0 )
return;
$grad = new Gradient($this->img);
if( $this->bkg_gradstyle == BGRAD_PLOT ) {
$xl = $this->img->left_margin;
$yt = $this->img->top_margin;
$xr = $xl + $this->img->plotwidth+1 ;
$yb = $yt + $this->img->plotheight ;
$grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype);
}
else {
$xl = 0;
$yt = 0;
$xr = $xl + $this->img->width - 1;
$yb = $yt + $this->img->height;
if( $this->doshadow ) {
$xr -= $this->shadow_width;
$yb -= $this->shadow_width;
}
if( $this->doframe ) {
$yt += $this->frame_weight;
$yb -= $this->frame_weight;
$xl += $this->frame_weight;
$xr -= $this->frame_weight;
}
$aa = $this->img->SetAngle(0);
$grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype);
$aa = $this->img->SetAngle($aa);
}
}
 
function StrokeFrameBackground() {
if( $this->background_image != "" && $this->background_cflag != "" ) {
JpGraphError::RaiseL(25040);//('It is not possible to specify both a background image and a background country flag.');
}
if( $this->background_image != "" ) {
$bkgimg = $this->LoadBkgImage($this->background_image_format,$this->background_image);
}
elseif( $this->background_cflag != "" ) {
if( ! class_exists('FlagImages') ) {
JpGraphError::RaiseL(25041);//('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.');
}
$fobj = new FlagImages(FLAGSIZE4);
$dummy='';
$bkgimg = $fobj->GetImgByName($this->background_cflag,$dummy);
$this->background_image_mix = $this->background_cflag_mix;
$this->background_image_type = $this->background_cflag_type;
}
else {
return ;
}
 
$bw = ImageSX($bkgimg);
$bh = ImageSY($bkgimg);
 
// No matter what the angle is we always stroke the image and frame
// assuming it is 0 degree
$aa = $this->img->SetAngle(0);
switch( $this->background_image_type ) {
case BGIMG_FILLPLOT: // Resize to just fill the plotarea
$this->FillMarginArea();
$this->StrokeFrame();
// Special case to hande 90 degree rotated graph corectly
if( $aa == 90 ) {
$this->img->SetAngle(90);
$this->FillPlotArea();
$aa = $this->img->SetAngle(0);
$adj = ($this->img->height - $this->img->width)/2;
$this->img->CopyMerge($bkgimg,
$this->img->bottom_margin-$adj,$this->img->left_margin+$adj,
0,0,
$this->img->plotheight+1,$this->img->plotwidth,
$bw,$bh,$this->background_image_mix);
 
}
else {
$this->FillPlotArea();
$this->img->CopyMerge($bkgimg,
$this->img->left_margin,$this->img->top_margin,
0,0,$this->img->plotwidth+1,$this->img->plotheight,
$bw,$bh,$this->background_image_mix);
}
break;
case BGIMG_FILLFRAME: // Fill the whole area from upper left corner, resize to just fit
$hadj=0; $vadj=0;
if( $this->doshadow ) {
$hadj = $this->shadow_width;
$vadj = $this->shadow_width;
}
$this->FillMarginArea();
$this->FillPlotArea();
$this->img->CopyMerge($bkgimg,0,0,0,0,$this->img->width-$hadj,$this->img->height-$vadj,
$bw,$bh,$this->background_image_mix);
$this->StrokeFrame();
break;
case BGIMG_COPY: // Just copy the image from left corner, no resizing
$this->FillMarginArea();
$this->FillPlotArea();
$this->img->CopyMerge($bkgimg,0,0,0,0,$bw,$bh,
$bw,$bh,$this->background_image_mix);
$this->StrokeFrame();
break;
case BGIMG_CENTER: // Center original image in the plot area
$this->FillMarginArea();
$this->FillPlotArea();
$centerx = round($this->img->plotwidth/2+$this->img->left_margin-$bw/2);
$centery = round($this->img->plotheight/2+$this->img->top_margin-$bh/2);
$this->img->CopyMerge($bkgimg,$centerx,$centery,0,0,$bw,$bh,
$bw,$bh,$this->background_image_mix);
$this->StrokeFrame();
break;
default:
JpGraphError::RaiseL(25042);//(" Unknown background image layout");
}
$this->img->SetAngle($aa);
}
 
// Private
// Draw a frame around the image
function StrokeFrame() {
if( !$this->doframe ) return;
 
if( $this->background_image_type <= 1 &&
($this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_PLOT)) ) {
$c = $this->margin_color;
}
else {
$c = false;
}
if( $this->doshadow ) {
$this->img->SetColor($this->frame_color);
$this->img->ShadowRectangle(0,0,$this->img->width,$this->img->height,
$c,$this->shadow_width,$this->shadow_color);
}
elseif( $this->framebevel ) {
if( $c ) {
$this->img->SetColor($this->margin_color);
$this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1);
}
$this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2,
$this->framebeveldepth,
$this->framebevelcolor1,$this->framebevelcolor2);
if( $this->framebevelborder ) {
$this->img->SetColor($this->framebevelbordercolor);
$this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1);
}
}
else {
$this->img->SetLineWeight($this->frame_weight);
if( $c ) {
$this->img->SetColor($this->margin_color);
$this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1);
}
$this->img->SetColor($this->frame_color);
$this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1);
}
}
 
function FillMarginArea() {
$hadj=0; $vadj=0;
if( $this->doshadow ) {
$hadj = $this->shadow_width;
$vadj = $this->shadow_width;
}
 
$this->img->SetColor($this->margin_color);
// $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->height-1-$vadj);
 
$this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->top_margin);
$this->img->FilledRectangle(0,$this->img->top_margin,$this->img->left_margin,$this->img->height-1-$hadj);
$this->img->FilledRectangle($this->img->left_margin+1,
$this->img->height-$this->img->bottom_margin,
$this->img->width-1-$hadj,
$this->img->height-1-$hadj);
$this->img->FilledRectangle($this->img->width-$this->img->right_margin,
$this->img->top_margin+1,
$this->img->width-1-$hadj,
$this->img->height-$this->img->bottom_margin-1);
}
 
function FillPlotArea() {
$this->img->PushColor($this->plotarea_color);
$this->img->FilledRectangle($this->img->left_margin,
$this->img->top_margin,
$this->img->width-$this->img->right_margin,
$this->img->height-$this->img->bottom_margin);
$this->img->PopColor();
}
// Stroke the plot area with either a solid color or a background image
function StrokePlotArea() {
// Note: To be consistent we really should take a possible shadow
// into account. However, that causes some problem for the LinearScale class
// since in the current design it does not have any links to class Graph which
// means it has no way of compensating for the adjusted plotarea in case of a
// shadow. So, until I redesign LinearScale we can't compensate for this.
// So just set the two adjustment parameters to zero for now.
$boxadj = 0; //$this->doframe ? $this->frame_weight : 0 ;
$adj = 0; //$this->doshadow ? $this->shadow_width : 0 ;
 
if( $this->background_image != "" || $this->background_cflag != "" ) {
$this->StrokeFrameBackground();
}
else {
$aa = $this->img->SetAngle(0);
$this->StrokeFrame();
$aa = $this->img->SetAngle($aa);
$this->StrokeBackgroundGrad();
if( $this->bkg_gradtype < 0 ||
($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_MARGIN) ) {
$this->FillPlotArea();
}
}
}
 
function StrokeIcons() {
$n = count($this->iIcons);
for( $i=0; $i < $n; ++$i ) {
$this->iIcons[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale);
}
}
function StrokePlotBox() {
// Should we draw a box around the plot area?
if( $this->boxed ) {
$this->img->SetLineWeight(1);
$this->img->SetLineStyle('solid');
$this->img->SetColor($this->box_color);
for($i=0; $i < $this->box_weight; ++$i ) {
$this->img->Rectangle(
$this->img->left_margin-$i,$this->img->top_margin-$i,
$this->img->width-$this->img->right_margin+$i,
$this->img->height-$this->img->bottom_margin+$i);
}
}
}
 
function SetTitleBackgroundFillStyle($aStyle,$aColor1='black',$aColor2='white') {
$this->titlebkg_fillstyle = $aStyle;
$this->titlebkg_scolor1 = $aColor1;
$this->titlebkg_scolor2 = $aColor2;
}
 
function SetTitleBackground($aBackColor='gray', $aStyle=TITLEBKG_STYLE1, $aFrameStyle=TITLEBKG_FRAME_NONE, $aFrameColor='black', $aFrameWeight=1, $aBevelHeight=3, $aEnable=true) {
$this->titlebackground = $aEnable;
$this->titlebackground_color = $aBackColor;
$this->titlebackground_style = $aStyle;
$this->titlebackground_framecolor = $aFrameColor;
$this->titlebackground_framestyle = $aFrameStyle;
$this->titlebackground_frameweight = $aFrameWeight;
$this->titlebackground_bevelheight = $aBevelHeight ;
}
 
 
function StrokeTitles() {
 
$margin=3;
 
if( $this->titlebackground ) {
 
// Find out height
$this->title->margin += 2 ;
$h = $this->title->GetTextHeight($this->img)+$this->title->margin+$margin;
if( $this->subtitle->t != "" && !$this->subtitle->hide ) {
$h += $this->subtitle->GetTextHeight($this->img)+$margin+
$this->subtitle->margin;
$h += 2;
}
if( $this->subsubtitle->t != "" && !$this->subsubtitle->hide ) {
$h += $this->subsubtitle->GetTextHeight($this->img)+$margin+
$this->subsubtitle->margin;
$h += 2;
}
$this->img->PushColor($this->titlebackground_color);
if( $this->titlebackground_style === TITLEBKG_STYLE1 ) {
// Inside the frame
if( $this->framebevel ) {
$x1 = $y1 = $this->framebeveldepth + 1 ;
$x2 = $this->img->width - $this->framebeveldepth - 2 ;
$this->title->margin += $this->framebeveldepth + 1 ;
$h += $y1 ;
$h += 2;
}
else {
$x1 = $y1 = $this->frame_weight;
$x2 = $this->img->width - 2*$x1;
}
}
elseif( $this->titlebackground_style === TITLEBKG_STYLE2 ) {
// Cover the frame as well
$x1 = $y1 = 0;
$x2 = $this->img->width - 1 ;
}
elseif( $this->titlebackground_style === TITLEBKG_STYLE3 ) {
// Cover the frame as well (the difference is that
// for style==3 a bevel frame border is on top
// of the title background)
$x1 = $y1 = 0;
$x2 = $this->img->width - 1 ;
$h += $this->framebeveldepth ;
$this->title->margin += $this->framebeveldepth ;
}
else {
JpGraphError::RaiseL(25043);//('Unknown title background style.');
}
 
if( $this->titlebackground_framestyle === 3 ) {
$h += $this->titlebackground_bevelheight*2 + 1 ;
$this->title->margin += $this->titlebackground_bevelheight ;
}
 
if( $this->doshadow ) {
$x2 -= $this->shadow_width ;
}
$indent=0;
if( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) {
$ind = $this->titlebackground_bevelheight;
}
 
if( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_HSTRIPED ) {
$this->img->FilledRectangle2($x1+$ind,$y1+$ind,$x2-$ind,$h-$ind,
$this->titlebkg_scolor1,
$this->titlebkg_scolor2);
}
elseif( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_VSTRIPED ) {
$this->img->FilledRectangle2($x1+$ind,$y1+$ind,$x2-$ind,$h-$ind,
$this->titlebkg_scolor1,
$this->titlebkg_scolor2,2);
}
else {
// Solid fill
$this->img->FilledRectangle($x1,$y1,$x2,$h);
}
$this->img->PopColor();
 
$this->img->PushColor($this->titlebackground_framecolor);
$this->img->SetLineWeight($this->titlebackground_frameweight);
if( $this->titlebackground_framestyle == TITLEBKG_FRAME_FULL ) {
// Frame background
$this->img->Rectangle($x1,$y1,$x2,$h);
}
elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BOTTOM ) {
// Bottom line only
$this->img->Line($x1,$h,$x2,$h);
}
elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) {
$this->img->Bevel($x1,$y1,$x2,$h,$this->titlebackground_bevelheight);
}
$this->img->PopColor();
 
// This is clumsy. But we neeed to stroke the whole graph frame if it is
// set to bevel to get the bevel shading on top of the text background
if( $this->framebevel && $this->doframe &&
$this->titlebackground_style === 3 ) {
$this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2,
$this->framebeveldepth,
$this->framebevelcolor1,$this->framebevelcolor2);
if( $this->framebevelborder ) {
$this->img->SetColor($this->framebevelbordercolor);
$this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1);
}
}
}
 
// Stroke title
$y = $this->title->margin;
if( $this->title->halign == 'center' )
$this->title->Center(0,$this->img->width,$y);
elseif( $this->title->halign == 'left' ) {
$this->title->SetPos($this->title->margin+2,$y);
}
elseif( $this->title->halign == 'right' ) {
$indent = 0;
if( $this->doshadow )
$indent = $this->shadow_width+2;
$this->title->SetPos($this->img->width-$this->title->margin-$indent,$y,'right');
}
$this->title->Stroke($this->img);
// ... and subtitle
$y += $this->title->GetTextHeight($this->img) + $margin + $this->subtitle->margin;
if( $this->subtitle->halign == 'center' )
$this->subtitle->Center(0,$this->img->width,$y);
elseif( $this->subtitle->halign == 'left' ) {
$this->subtitle->SetPos($this->subtitle->margin+2,$y);
}
elseif( $this->subtitle->halign == 'right' ) {
$indent = 0;
if( $this->doshadow )
$indent = $this->shadow_width+2;
$this->subtitle->SetPos($this->img->width-$this->subtitle->margin-$indent,$y,'right');
}
$this->subtitle->Stroke($this->img);
 
// ... and subsubtitle
$y += $this->subtitle->GetTextHeight($this->img) + $margin + $this->subsubtitle->margin;
if( $this->subsubtitle->halign == 'center' )
$this->subsubtitle->Center(0,$this->img->width,$y);
elseif( $this->subsubtitle->halign == 'left' ) {
$this->subsubtitle->SetPos($this->subsubtitle->margin+2,$y);
}
elseif( $this->subsubtitle->halign == 'right' ) {
$indent = 0;
if( $this->doshadow )
$indent = $this->shadow_width+2;
$this->subsubtitle->SetPos($this->img->width-$this->subsubtitle->margin-$indent,$y,'right');
}
$this->subsubtitle->Stroke($this->img);
 
// ... and fancy title
$this->tabtitle->Stroke($this->img);
 
}
 
function StrokeTexts() {
// Stroke any user added text objects
if( $this->texts != null ) {
for($i=0; $i < count($this->texts); ++$i) {
$this->texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale);
}
}
 
if( $this->y2texts != null && $this->y2scale != null ) {
for($i=0; $i < count($this->y2texts); ++$i) {
$this->y2texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->y2scale);
}
}
 
}
 
function StrokeTables() {
if( $this->iTables != null ) {
$n = count($this->iTables);
for( $i=0; $i < $n; ++$i ) {
$this->iTables[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale);
}
}
}
 
function DisplayClientSideaImageMapAreas() {
// Debug stuff - display the outline of the image map areas
$csim='';
foreach ($this->plots as $p) {
$csim.= $p->GetCSIMareas();
}
$csim .= $this->legend->GetCSIMareas();
if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) {
$this->img->SetColor($this->csimcolor);
$n = count($coords[0]);
for ($i=0; $i < $n; $i++) {
if ($coords[1][$i]=="poly") {
preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts);
$this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]);
$m = count($pts[0]);
for ($j=0; $j < $m; $j++) {
$this->img->LineTo($pts[1][$j],$pts[2][$j]);
}
} else if ($coords[1][$i]=="rect") {
$pts = preg_split('/,/', $coords[2][$i]);
$this->img->SetStartPoint($pts[0],$pts[1]);
$this->img->LineTo($pts[2],$pts[1]);
$this->img->LineTo($pts[2],$pts[3]);
$this->img->LineTo($pts[0],$pts[3]);
$this->img->LineTo($pts[0],$pts[1]);
}
}
}
}
 
// Text scale offset in fractions of a major scale step
function SetTextScaleOff($aOff) {
$this->text_scale_off = $aOff;
$this->xscale->text_scale_off = $aOff;
}
 
// Text width of bar to be centered in absolute pixels
function SetTextScaleAbsCenterOff($aOff) {
$this->text_scale_abscenteroff = $aOff;
}
 
// Get Y min and max values for added lines
function GetLinesYMinMax( $aLines ) {
$n = count($aLines);
if( $n == 0 ) return false;
$min = $aLines[0]->scaleposition ;
$max = $min ;
$flg = false;
for( $i=0; $i < $n; ++$i ) {
if( $aLines[$i]->direction == HORIZONTAL ) {
$flg = true ;
$v = $aLines[$i]->scaleposition ;
if( $min > $v ) $min = $v ;
if( $max < $v ) $max = $v ;
}
}
return $flg ? array($min,$max) : false ;
}
 
// Get X min and max values for added lines
function GetLinesXMinMax( $aLines ) {
$n = count($aLines);
if( $n == 0 ) return false ;
$min = $aLines[0]->scaleposition ;
$max = $min ;
$flg = false;
for( $i=0; $i < $n; ++$i ) {
if( $aLines[$i]->direction == VERTICAL ) {
$flg = true ;
$v = $aLines[$i]->scaleposition ;
if( $min > $v ) $min = $v ;
if( $max < $v ) $max = $v ;
}
}
return $flg ? array($min,$max) : false ;
}
 
// Get min and max values for all included plots
function GetPlotsYMinMax(&$aPlots) {
$n = count($aPlots);
$i=0;
do {
list($xmax,$max) = $aPlots[$i]->Max();
} while( ++$i < $n && !is_numeric($max) );
$i=0;
do {
list($xmin,$min) = $aPlots[$i]->Min();
} while( ++$i < $n && !is_numeric($min) );
if( !is_numeric($min) || !is_numeric($max) ) {
JpGraphError::RaiseL(25044);//('Cannot use autoscaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).');
}
 
list($xmax,$max) = $aPlots[0]->Max();
list($xmin,$min) = $aPlots[0]->Min();
for($i=0; $i < count($aPlots); ++$i ) {
list($xmax,$ymax)=$aPlots[$i]->Max();
list($xmin,$ymin)=$aPlots[$i]->Min();
if (is_numeric($ymax)) $max=max($max,$ymax);
if (is_numeric($ymin)) $min=min($min,$ymin);
}
if( $min == '' ) $min = 0;
if( $max == '' ) $max = 0;
if( $min == 0 && $max == 0 ) {
// Special case if all values are 0
$min=0;$max=1;
}
return array($min,$max);
}
 
} // Class
 
 
 
//===================================================
// CLASS LineProperty
// Description: Holds properties for a line
//===================================================
class LineProperty {
var $iWeight=1, $iColor="black",$iStyle="solid";
var $iShow=true;
//---------------
// PUBLIC METHODS
function SetColor($aColor) {
$this->iColor = $aColor;
}
function SetWeight($aWeight) {
$this->iWeight = $aWeight;
}
function SetStyle($aStyle) {
$this->iStyle = $aStyle;
}
function Show($aShow=true) {
$this->iShow=$aShow;
}
function Stroke(&$aImg,$aX1,$aY1,$aX2,$aY2) {
if( $this->iShow ) {
$aImg->PushColor($this->iColor);
$oldls = $aImg->line_style;
$oldlw = $aImg->line_weight;
$aImg->SetLineWeight($this->iWeight);
$aImg->SetLineStyle($this->iStyle);
$aImg->StyleLine($aX1,$aY1,$aX2,$aY2);
$aImg->PopColor($this->iColor);
$aImg->line_style = $oldls;
$aImg->line_weight = $oldlw;
 
}
}
}
 
 
//===================================================
// CLASS Text
// Description: Arbitrary text object that can be added to the graph
//===================================================
class Text {
var $t,$x=0,$y=0,$halign="left",$valign="top",$color=array(0,0,0);
var $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=10;
var $hide=false, $dir=0;
var $boxed=false; // Should the text be boxed
var $paragraph_align="left";
var $margin=0;
var $icornerradius=0,$ishadowwidth=3;
var $iScalePosY=null,$iScalePosX=null;
var $iWordwrap=0;
var $fcolor='white',$bcolor='black',$shadow=false;
var $iCSIMarea='',$iCSIMalt='',$iCSIMtarget='',$iCSIMWinTarget='';
 
//---------------
// CONSTRUCTOR
 
// Create new text at absolute pixel coordinates
function Text($aTxt='',$aXAbsPos=0,$aYAbsPos=0) {
if( ! is_string($aTxt) ) {
JpGraphError::RaiseL(25050);//('First argument to Text::Text() must be s atring.');
}
$this->t = $aTxt;
$this->x = round($aXAbsPos);
$this->y = round($aYAbsPos);
$this->margin = 0;
}
//---------------
// PUBLIC METHODS
// Set the string in the text object
function Set($aTxt) {
$this->t = $aTxt;
}
// Alias for Pos()
function SetPos($aXAbsPos=0,$aYAbsPos=0,$aHAlign="left",$aVAlign="top") {
$this->Pos($aXAbsPos,$aYAbsPos,$aHAlign,$aVAlign);
}
// Specify the position and alignment for the text object
function Pos($aXAbsPos=0,$aYAbsPos=0,$aHAlign="left",$aVAlign="top") {
$this->x = $aXAbsPos;
$this->y = $aYAbsPos;
$this->halign = $aHAlign;
$this->valign = $aVAlign;
}
 
function SetScalePos($aX,$aY) {
$this->iScalePosX = $aX;
$this->iScalePosY = $aY;
}
// Specify alignment for the text
function Align($aHAlign,$aVAlign="top",$aParagraphAlign="") {
$this->halign = $aHAlign;
$this->valign = $aVAlign;
if( $aParagraphAlign != "" )
$this->paragraph_align = $aParagraphAlign;
}
// Alias
function SetAlign($aHAlign,$aVAlign="top",$aParagraphAlign="") {
$this->Align($aHAlign,$aVAlign,$aParagraphAlign);
}
 
// Specifies the alignment for a multi line text
function ParagraphAlign($aAlign) {
$this->paragraph_align = $aAlign;
}
 
// Specifies the alignment for a multi line text
function SetParagraphAlign($aAlign) {
$this->paragraph_align = $aAlign;
}
 
function SetShadow($aShadowColor='darkgray',$aShadowWidth=3) {
$this->ishadowwidth=$aShadowWidth;
$this->shadow=$aShadowColor;
$this->boxed=true;
}
 
function SetWordWrap($aCol) {
$this->iWordwrap = $aCol ;
}
// Specify that the text should be boxed. fcolor=frame color, bcolor=border color,
// $shadow=drop shadow should be added around the text.
function SetBox($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) {
if( $aFrameColor==false )
$this->boxed=false;
else
$this->boxed=true;
$this->fcolor=$aFrameColor;
$this->bcolor=$aBorderColor;
// For backwards compatibility when shadow was just true or false
if( $aShadowColor === true )
$aShadowColor = 'gray';
$this->shadow=$aShadowColor;
$this->icornerradius=$aCornerRadius;
$this->ishadowwidth=$aShadowWidth;
}
// Hide the text
function Hide($aHide=true) {
$this->hide=$aHide;
}
// This looks ugly since it's not a very orthogonal design
// but I added this "inverse" of Hide() to harmonize
// with some classes which I designed more recently (especially)
// jpgraph_gantt
function Show($aShow=true) {
$this->hide=!$aShow;
}
// Specify font
function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) {
$this->font_family=$aFamily;
$this->font_style=$aStyle;
$this->font_size=$aSize;
}
// Center the text between $left and $right coordinates
function Center($aLeft,$aRight,$aYAbsPos=false) {
$this->x = $aLeft + ($aRight-$aLeft )/2;
$this->halign = "center";
if( is_numeric($aYAbsPos) )
$this->y = $aYAbsPos;
}
// Set text color
function SetColor($aColor) {
$this->color = $aColor;
}
function SetAngle($aAngle) {
$this->SetOrientation($aAngle);
}
// Orientation of text. Note only TTF fonts can have an arbitrary angle
function SetOrientation($aDirection=0) {
if( is_numeric($aDirection) )
$this->dir=$aDirection;
elseif( $aDirection=="h" )
$this->dir = 0;
elseif( $aDirection=="v" )
$this->dir = 90;
else JpGraphError::RaiseL(25051);//(" Invalid direction specified for text.");
}
// Total width of text
function GetWidth(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$w = $aImg->GetTextWidth($this->t,$this->dir);
return $w;
}
// Hight of font
function GetFontHeight(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$h = $aImg->GetFontHeight();
return $h;
 
}
 
function GetTextHeight(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$h = $aImg->GetTextHeight($this->t,$this->dir);
return $h;
}
 
function GetHeight(&$aImg) {
// Synonym for GetTextHeight()
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$h = $aImg->GetTextHeight($this->t,$this->dir);
return $h;
}
 
// Set the margin which will be interpretated differently depending
// on the context.
function SetMargin($aMarg) {
$this->margin = $aMarg;
}
 
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 SetCSIMTarget($aURITarget,$aAlt='',$aWinTarget='') {
$this->iCSIMtarget = $aURITarget;
$this->iCSIMalt = $aAlt;
$this->iCSIMWinTarget = $aWinTarget;
}
 
function GetCSIMareas() {
if( $this->iCSIMtarget !== '' )
return $this->iCSIMarea;
else
return '';
}
 
// Display text in image
function Stroke(&$aImg,$x=null,$y=null) {
 
if( !empty($x) ) $this->x = round($x);
if( !empty($y) ) $this->y = round($y);
 
// Insert newlines
if( $this->iWordwrap > 0 ) {
$this->t = wordwrap($this->t,$this->iWordwrap,"\n");
}
 
// If position been given as a fraction of the image size
// calculate the absolute position
if( $this->x < 1 && $this->x > 0 ) $this->x *= $aImg->width;
if( $this->y < 1 && $this->y > 0 ) $this->y *= $aImg->height;
 
$aImg->PushColor($this->color);
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$aImg->SetTextAlign($this->halign,$this->valign);
if( $this->boxed ) {
if( $this->fcolor=="nofill" )
$this->fcolor=false;
$aImg->SetLineWeight(1);
$bbox = $aImg->StrokeBoxedText($this->x,$this->y,$this->t,
$this->dir,$this->fcolor,$this->bcolor,$this->shadow,
$this->paragraph_align,5,5,$this->icornerradius,
$this->ishadowwidth);
}
else {
$bbox = $aImg->StrokeText($this->x,$this->y,$this->t,$this->dir,$this->paragraph_align);
}
 
// Create CSIM targets
$coords = $bbox[0].','.$bbox[1].','.$bbox[2].','.$bbox[3].','.$bbox[4].','.$bbox[5].','.$bbox[6].','.$bbox[7];
$this->iCSIMarea = "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->iCSIMtarget)."\" ";
if( trim($this->iCSIMalt) != '' ) {
$this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" ";
$this->iCSIMarea .= " title=\"".$this->iCSIMalt."\" ";
}
if( trim($this->iCSIMWinTarget) != '' ) {
$this->iCSIMarea .= " target=\"".$this->iCSIMWinTarget."\" ";
}
$this->iCSIMarea .= " />\n";
 
$aImg->PopColor($this->color);
 
}
} // Class
 
class GraphTabTitle extends Text{
var $corner = 6 , $posx = 7, $posy = 4;
var $color='darkred',$fillcolor='lightyellow',$bordercolor='black';
var $align = 'left', $width=TABTITLE_WIDTHFIT;
function GraphTabTitle() {
$this->t = '';
$this->font_style = FS_BOLD;
$this->hide = true;
}
 
function SetColor($aTxtColor,$aFillColor='lightyellow',$aBorderColor='black') {
$this->color = $aTxtColor;
$this->fillcolor = $aFillColor;
$this->bordercolor = $aBorderColor;
}
 
function SetFillColor($aFillColor) {
$this->fillcolor = $aFillColor;
}
 
function SetTabAlign($aAlign) {
// Synonym for SetPos
$this->align = $aAlign;
}
 
function SetPos($aAlign) {
$this->align = $aAlign;
}
function SetWidth($aWidth) {
$this->width = $aWidth ;
}
 
function Set($t) {
$this->t = $t;
$this->hide = false;
}
 
function SetCorner($aD) {
$this->corner = $aD ;
}
 
function Stroke(&$aImg) {
if( $this->hide )
return;
$this->boxed = false;
$w = $this->GetWidth($aImg) + 2*$this->posx;
$h = $this->GetTextHeight($aImg) + 2*$this->posy;
 
$x = $aImg->left_margin;
$y = $aImg->top_margin;
 
if( $this->width === TABTITLE_WIDTHFIT ) {
if( $this->align == 'left' ) {
$p = array($x, $y,
$x, $y-$h+$this->corner,
$x + $this->corner,$y-$h,
$x + $w - $this->corner, $y-$h,
$x + $w, $y-$h+$this->corner,
$x + $w, $y);
}
elseif( $this->align == 'center' ) {
$x += round($aImg->plotwidth/2) - round($w/2);
$p = array($x, $y,
$x, $y-$h+$this->corner,
$x + $this->corner, $y-$h,
$x + $w - $this->corner, $y-$h,
$x + $w, $y-$h+$this->corner,
$x + $w, $y);
}
else {
$x += $aImg->plotwidth -$w;
$p = array($x, $y,
$x, $y-$h+$this->corner,
$x + $this->corner,$y-$h,
$x + $w - $this->corner, $y-$h,
$x + $w, $y-$h+$this->corner,
$x + $w, $y);
}
}
else {
if( $this->width === TABTITLE_WIDTHFULL )
$w = $aImg->plotwidth ;
else
$w = $this->width ;
 
// Make the tab fit the width of the plot area
$p = array($x, $y,
$x, $y-$h+$this->corner,
$x + $this->corner,$y-$h,
$x + $w - $this->corner, $y-$h,
$x + $w, $y-$h+$this->corner,
$x + $w, $y);
}
if( $this->halign == 'left' ) {
$aImg->SetTextAlign('left','bottom');
$x += $this->posx;
$y -= $this->posy;
}
elseif( $this->halign == 'center' ) {
$aImg->SetTextAlign('center','bottom');
$x += $w/2;
$y -= $this->posy;
}
else {
$aImg->SetTextAlign('right','bottom');
$x += $w - $this->posx;
$y -= $this->posy;
}
 
$aImg->SetColor($this->fillcolor);
$aImg->FilledPolygon($p);
 
$aImg->SetColor($this->bordercolor);
$aImg->Polygon($p,true);
$aImg->SetColor($this->color);
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$aImg->StrokeText($x,$y,$this->t,0,'center');
}
 
}
 
//===================================================
// CLASS SuperScriptText
// Description: Format a superscript text
//===================================================
class SuperScriptText extends Text {
var $iSuper="";
var $sfont_family="",$sfont_style="",$sfont_size=8;
var $iSuperMargin=2,$iVertOverlap=4,$iSuperScale=0.65;
var $iSDir=0;
var $iSimple=false;
 
function SuperScriptText($aTxt="",$aSuper="",$aXAbsPos=0,$aYAbsPos=0) {
parent::Text($aTxt,$aXAbsPos,$aYAbsPos);
$this->iSuper = $aSuper;
}
 
function FromReal($aVal,$aPrecision=2) {
// Convert a floating point number to scientific notation
$neg=1.0;
if( $aVal < 0 ) {
$neg = -1.0;
$aVal = -$aVal;
}
$l = floor(log10($aVal));
$a = sprintf("%0.".$aPrecision."f",round($aVal / pow(10,$l),$aPrecision));
$a *= $neg;
if( $this->iSimple && ($a == 1 || $a==-1) ) $a = '';
if( $a != '' )
$this->t = $a.' * 10';
else {
if( $neg == 1 )
$this->t = '10';
else
$this->t = '-10';
}
$this->iSuper = $l;
}
 
function Set($aTxt,$aSuper="") {
$this->t = $aTxt;
$this->iSuper = $aSuper;
}
 
function SetSuperFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=8) {
$this->sfont_family = $aFontFam;
$this->sfont_style = $aFontStyle;
$this->sfont_size = $aFontSize;
}
 
// Total width of text
function GetWidth(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$w = $aImg->GetTextWidth($this->t);
$aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size);
$w += $aImg->GetTextWidth($this->iSuper);
$w += $this->iSuperMargin;
return $w;
}
// Hight of font (approximate the height of the text)
function GetFontHeight(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$h = $aImg->GetFontHeight();
$aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size);
$h += $aImg->GetFontHeight();
return $h;
}
 
// Hight of text
function GetTextHeight(&$aImg) {
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$h = $aImg->GetTextHeight($this->t);
$aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size);
$h += $aImg->GetTextHeight($this->iSuper);
return $h;
}
 
function Stroke(&$aImg,$ax=-1,$ay=-1) {
// To position the super script correctly we need different
// cases to handle the alignmewnt specified since that will
// determine how we can interpret the x,y coordinates
$w = parent::GetWidth($aImg);
$h = parent::GetTextHeight($aImg);
switch( $this->valign ) {
case 'top':
$sy = $this->y;
break;
case 'center':
$sy = $this->y - $h/2;
break;
case 'bottom':
$sy = $this->y - $h;
break;
default:
JpGraphError::RaiseL(25052);//('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text');
break;
}
 
switch( $this->halign ) {
case 'left':
$sx = $this->x + $w;
break;
case 'center':
$sx = $this->x + $w/2;
break;
case 'right':
$sx = $this->x;
break;
default:
JpGraphError::RaiseL(25053);//('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text');
break;
}
 
$sx += $this->iSuperMargin;
$sy += $this->iVertOverlap;
 
// Should we automatically determine the font or
// has the user specified it explicetly?
if( $this->sfont_family == "" ) {
if( $this->font_family <= FF_FONT2 ) {
if( $this->font_family == FF_FONT0 ) {
$sff = FF_FONT0;
}
elseif( $this->font_family == FF_FONT1 ) {
if( $this->font_style == FS_NORMAL )
$sff = FF_FONT0;
else
$sff = FF_FONT1;
}
else {
$sff = FF_FONT1;
}
$sfs = $this->font_style;
$sfz = $this->font_size;
}
else {
// TTF fonts
$sff = $this->font_family;
$sfs = $this->font_style;
$sfz = floor($this->font_size*$this->iSuperScale);
if( $sfz < 8 ) $sfz = 8;
}
$this->sfont_family = $sff;
$this->sfont_style = $sfs;
$this->sfont_size = $sfz;
}
else {
$sff = $this->sfont_family;
$sfs = $this->sfont_style;
$sfz = $this->sfont_size;
}
 
parent::Stroke($aImg,$ax,$ay);
 
 
// For the builtin fonts we need to reduce the margins
// since the bounding bx reported for the builtin fonts
// are much larger than for the TTF fonts.
if( $sff <= FF_FONT2 ) {
$sx -= 2;
$sy += 3;
}
 
$aImg->SetTextAlign('left','bottom');
$aImg->SetFont($sff,$sfs,$sfz);
$aImg->PushColor($this->color);
$aImg->StrokeText($sx,$sy,$this->iSuper,$this->iSDir,'left');
$aImg->PopColor();
}
}
 
 
//===================================================
// CLASS Grid
// Description: responsible for drawing grid lines in graph
//===================================================
class Grid {
var $img;
var $scale;
var $grid_color='#DDDDDD',$grid_mincolor='#DDDDDD';
var $type="solid";
var $show=false, $showMinor=false,$weight=1;
var $fill=false,$fillcolor=array('#EFEFEF','#BBCCFF');
//---------------
// CONSTRUCTOR
function Grid(&$aAxis) {
$this->scale = &$aAxis->scale;
$this->img = &$aAxis->img;
}
//---------------
// PUBLIC METHODS
function SetColor($aMajColor,$aMinColor=false) {
$this->grid_color=$aMajColor;
if( $aMinColor === false )
$aMinColor = $aMajColor ;
$this->grid_mincolor = $aMinColor;
}
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,$aShowMinor=false) {
$this->show=$aShowMajor;
$this->showMinor=$aShowMinor;
}
function SetFill($aFlg=true,$aColor1='lightgray',$aColor2='lightblue') {
$this->fill = $aFlg;
$this->fillcolor = array( $aColor1, $aColor2 );
}
// Display the grid
function Stroke() {
 
// We do not have minor ticks (or grids) for text scales
if( $this->showMinor && !$this->scale->textscale ) {
$tmp = $this->grid_color;
$this->grid_color = $this->grid_mincolor;
$this->DoStroke($this->scale->ticks->ticks_pos);
 
$this->grid_color = $tmp;
$this->DoStroke($this->scale->ticks->maj_ticks_pos);
}
else {
$this->DoStroke($this->scale->ticks->maj_ticks_pos);
}
}
//--------------
// Private methods
// Draw the grid
function DoStroke(&$aTicksPos) {
if( !$this->show )
return;
$nbrgrids = count($aTicksPos);
 
if( $this->scale->type=="y" ) {
$xl=$this->img->left_margin;
$xr=$this->img->width-$this->img->right_margin;
if( $this->fill ) {
// Draw filled areas
$y2 = $aTicksPos[0];
$i=1;
while( $i < $nbrgrids ) {
$y1 = $y2;
$y2 = $aTicksPos[$i++];
$this->img->SetColor($this->fillcolor[$i & 1]);
$this->img->FilledRectangle($xl,$y1,$xr,$y2);
}
}
 
$this->img->SetColor($this->grid_color);
$this->img->SetLineWeight($this->weight);
 
// Draw grid lines
for($i=0; $i<$nbrgrids; ++$i) {
$y=$aTicksPos[$i];
if( $this->type == "solid" )
$this->img->Line($xl,$y,$xr,$y);
elseif( $this->type == "dotted" )
$this->img->DashedLine($xl,$y,$xr,$y,1,6);
elseif( $this->type == "dashed" )
$this->img->DashedLine($xl,$y,$xr,$y,2,4);
elseif( $this->type == "longdashed" )
$this->img->DashedLine($xl,$y,$xr,$y,8,6);
}
}
elseif( $this->scale->type=="x" ) {
$yu=$this->img->top_margin;
$yl=$this->img->height-$this->img->bottom_margin;
$limit=$this->img->width-$this->img->right_margin;
 
if( $this->fill ) {
// Draw filled areas
$x2 = $aTicksPos[0];
$i=1;
while( $i < $nbrgrids ) {
$x1 = $x2;
$x2 = min($aTicksPos[$i++],$limit) ;
$this->img->SetColor($this->fillcolor[$i & 1]);
$this->img->FilledRectangle($x1,$yu,$x2,$yl);
}
}
 
$this->img->SetColor($this->grid_color);
$this->img->SetLineWeight($this->weight);
 
// We must also test for limit since we might have
// an offset and the number of ticks is calculated with
// assumption offset==0 so we might end up drawing one
// to many gridlines
$i=0;
$x=$aTicksPos[$i];
while( $i<count($aTicksPos) && ($x=$aTicksPos[$i]) <= $limit ) {
if( $this->type == "solid" )
$this->img->Line($x,$yl,$x,$yu);
elseif( $this->type == "dotted" )
$this->img->DashedLine($x,$yl,$x,$yu,1,6);
elseif( $this->type == "dashed" )
$this->img->DashedLine($x,$yl,$x,$yu,2,4);
elseif( $this->type == "longdashed" )
$this->img->DashedLine($x,$yl,$x,$yu,8,6);
++$i;
}
}
else {
JpGraphError::RaiseL(25054,$this->scale->type);//('Internal error: Unknown grid axis ['.$this->scale->type.']');
}
return true;
}
} // Class
 
//===================================================
// CLASS Axis
// Description: Defines X and Y axis. Notes that at the
// moment the code is not really good since the axis on
// several occasion must know wheter it's an X or Y axis.
// This was a design decision to make the code easier to
// follow.
//===================================================
class Axis {
var $pos = false;
var $weight=1;
var $color=array(0,0,0),$label_color=array(0,0,0);
var $img=null,$scale=null;
var $hide=false;
var $ticks_label=false, $ticks_label_colors=null;
var $show_first_label=true,$show_last_label=true;
var $label_step=1; // Used by a text axis to specify what multiple of major steps
// should be labeled.
var $tick_step=1;
var $labelPos=0; // Which side of the axis should the labels be?
var $title=null,$title_adjust,$title_margin,$title_side=SIDE_LEFT;
var $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=10,$label_angle=0;
var $tick_label_margin=7;
var $label_halign = '',$label_valign = '', $label_para_align='left';
var $hide_line=false,$hide_labels=false;
var $iDeltaAbsPos=0;
//var $hide_zero_label=false;
 
//---------------
// CONSTRUCTOR
function Axis(&$img,&$aScale,$color=array(0,0,0)) {
$this->img = &$img;
$this->scale = &$aScale;
$this->color = $color;
$this->title=new Text("");
if( $aScale->type=="y" ) {
$this->title_margin = 25;
$this->title_adjust="middle";
$this->title->SetOrientation(90);
$this->tick_label_margin=7;
$this->labelPos=SIDE_LEFT;
//$this->SetLabelFormat('%.1f');
}
else {
$this->title_margin = 5;
$this->title_adjust="high";
$this->title->SetOrientation(0);
$this->tick_label_margin=7;
$this->labelPos=SIDE_DOWN;
$this->title_side=SIDE_DOWN;
//$this->SetLabelFormat('%.0f');
}
}
//---------------
// PUBLIC METHODS
function SetLabelFormat($aFormStr) {
$this->scale->ticks->SetLabelFormat($aFormStr);
}
function SetLabelFormatString($aFormStr,$aDate=false) {
$this->scale->ticks->SetLabelFormat($aFormStr,$aDate);
}
function SetLabelFormatCallback($aFuncName) {
$this->scale->ticks->SetFormatCallback($aFuncName);
}
 
function SetLabelAlign($aHAlign,$aVAlign="top",$aParagraphAlign='left') {
$this->label_halign = $aHAlign;
$this->label_valign = $aVAlign;
$this->label_para_align = $aParagraphAlign;
}
 
// Don't display the first label
function HideFirstTickLabel($aShow=false) {
$this->show_first_label=$aShow;
}
 
function HideLastTickLabel($aShow=false) {
$this->show_last_label=$aShow;
}
 
// Manually specify the major and (optional) minor tick position and labels
function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) {
$this->scale->ticks->SetTickPositions($aMajPos,$aMinPos,$aLabels);
}
 
// Manually specify major tick positions and optional labels
function SetMajTickPositions($aMajPos,$aLabels=NULL) {
$this->scale->ticks->SetTickPositions($aMajPos,NULL,$aLabels);
}
 
// Hide minor or major tick marks
function HideTicks($aHideMinor=true,$aHideMajor=true) {
$this->scale->ticks->SupressMinorTickMarks($aHideMinor);
$this->scale->ticks->SupressTickMarks($aHideMajor);
}
 
// Hide zero label
function HideZeroLabel($aFlag=true) {
$this->scale->ticks->SupressZeroLabel();
//$this->hide_zero_label = $aFlag;
}
function HideFirstLastLabel() {
// The two first calls to ticks method will supress
// automatically generated scale values. However, that
// will not affect manually specified value, e.g text-scales.
// therefor we also make a kludge here to supress manually
// specified scale labels.
$this->scale->ticks->SupressLast();
$this->scale->ticks->SupressFirst();
$this->show_first_label = false;
$this->show_last_label = false;
}
// Hide the axis
function Hide($aHide=true) {
$this->hide=$aHide;
}
 
// Hide the actual axis-line, but still print the labels
function HideLine($aHide=true) {
$this->hide_line = $aHide;
}
 
function HideLabels($aHide=true) {
$this->hide_labels = $aHide;
}
 
// Weight of axis
function SetWeight($aWeight) {
$this->weight = $aWeight;
}
 
// Axis color
function SetColor($aColor,$aLabelColor=false) {
$this->color = $aColor;
if( !$aLabelColor ) $this->label_color = $aColor;
else $this->label_color = $aLabelColor;
}
// Title on axis
function SetTitle($aTitle,$aAdjustAlign="high") {
$this->title->Set($aTitle);
$this->title_adjust=$aAdjustAlign;
}
// Specify distance from the axis
function SetTitleMargin($aMargin) {
$this->title_margin=$aMargin;
}
// Which side of the axis should the axis title be?
function SetTitleSide($aSideOfAxis) {
$this->title_side = $aSideOfAxis;
}
 
// Utility function to set the direction for tick marks
function SetTickDirection($aDir) {
// Will be deprecated from 1.7
if( ERR_DEPRECATED )
JpGraphError::RaiseL(25055);//('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead');
$this->scale->ticks->SetSide($aDir);
}
function SetTickSide($aDir) {
$this->scale->ticks->SetSide($aDir);
}
// Specify text labels for the ticks. One label for each data point
function SetTickLabels($aLabelArray,$aLabelColorArray=null) {
$this->ticks_label = $aLabelArray;
$this->ticks_label_colors = $aLabelColorArray;
}
// How far from the axis should the labels be drawn
function SetTickLabelMargin($aMargin) {
if( ERR_DEPRECATED )
JpGraphError::RaiseL(25056);//('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.');
$this->tick_label_margin=$aMargin;
}
 
function SetLabelMargin($aMargin) {
$this->tick_label_margin=$aMargin;
}
// Specify that every $step of the ticks should be displayed starting
// at $start
// DEPRECATED FUNCTION: USE SetTextTickInterval() INSTEAD
function SetTextTicks($step,$start=0) {
JpGraphError::RaiseL(25057);//(" SetTextTicks() is deprecated. Use SetTextTickInterval() instead.");
}
 
// Specify that every $step of the ticks should be displayed starting
// at $start
function SetTextTickInterval($aStep,$aStart=0) {
$this->scale->ticks->SetTextLabelStart($aStart);
$this->tick_step=$aStep;
}
// Specify that every $step tick mark should have a label
// should be displayed starting
function SetTextLabelInterval($aStep,$aStart=0) {
if( $aStep < 1 )
JpGraphError::RaiseL(25058);//(" Text label interval must be specified >= 1.");
$this->scale->ticks->SetTextLabelStart($aStart);
$this->label_step=$aStep;
}
// Which side of the axis should the labels be on?
function SetLabelPos($aSidePos) {
// This will be deprecated from 1.7
if( ERR_DEPRECATED )
JpGraphError::RaiseL(25059);//('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.');
$this->labelPos=$aSidePos;
}
function SetLabelSide($aSidePos) {
$this->labelPos=$aSidePos;
}
 
// Set the font
function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) {
$this->font_family = $aFamily;
$this->font_style = $aStyle;
$this->font_size = $aSize;
}
 
// Position for axis line on the "other" scale
function SetPos($aPosOnOtherScale) {
$this->pos=$aPosOnOtherScale;
}
 
// Set the position of the axis to be X-pixels delta to the right
// of the max X-position (used to position the multiple Y-axis)
function SetPosAbsDelta($aDelta) {
$this->iDeltaAbsPos=$aDelta;
}
// Specify the angle for the tick labels
function SetLabelAngle($aAngle) {
$this->label_angle = $aAngle;
}
// Stroke the axis.
function Stroke($aOtherAxisScale,$aStrokeLabels=true) {
if( $this->hide ) return;
if( is_numeric($this->pos) ) {
$pos=$aOtherAxisScale->Translate($this->pos);
}
else { // Default to minimum of other scale if pos not set
if( ($aOtherAxisScale->GetMinVal() >= 0 && $this->pos==false) || $this->pos=="min" ) {
$pos = $aOtherAxisScale->scale_abs[0];
}
elseif($this->pos == "max") {
$pos = $aOtherAxisScale->scale_abs[1];
}
else { // If negative set x-axis at 0
$this->pos=0;
$pos=$aOtherAxisScale->Translate(0);
}
}
$pos += $this->iDeltaAbsPos;
$this->img->SetLineWeight($this->weight);
$this->img->SetColor($this->color);
$this->img->SetFont($this->font_family,$this->font_style,$this->font_size);
if( $this->scale->type == "x" ) {
if( !$this->hide_line )
$this->img->FilledRectangle($this->img->left_margin,$pos,
$this->img->width-$this->img->right_margin,$pos+$this->weight-1);
if( $this->title_side == SIDE_DOWN ) {
$y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin;
$yalign = 'top';
}
else {
$y = $pos - $this->img->GetFontHeight() - $this->title_margin - $this->title->margin;
$yalign = 'bottom';
}
 
if( $this->title_adjust=="high" )
$this->title->Pos($this->img->width-$this->img->right_margin,$y,"right",$yalign);
elseif( $this->title_adjust=="middle" || $this->title_adjust=="center" )
$this->title->Pos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin,$y,"center",$yalign);
elseif($this->title_adjust=="low")
$this->title->Pos($this->img->left_margin,$y,"left",$yalign);
else {
JpGraphError::RaiseL(25060,$this->title_adjust);//('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')');
}
}
elseif( $this->scale->type == "y" ) {
// Add line weight to the height of the axis since
// the x-axis could have a width>1 and we want the axis to fit nicely together.
if( !$this->hide_line )
$this->img->FilledRectangle($pos-$this->weight+1,$this->img->top_margin,
$pos,$this->img->height-$this->img->bottom_margin+$this->weight-1);
$x=$pos ;
if( $this->title_side == SIDE_LEFT ) {
$x -= $this->title_margin;
$x -= $this->title->margin;
$halign="right";
}
else {
$x += $this->title_margin;
$x += $this->title->margin;
$halign="left";
}
// If the user has manually specified an hor. align
// then we override the automatic settings with this
// specifed setting. Since default is 'left' we compare
// with that. (This means a manually set 'left' align
// will have no effect.)
if( $this->title->halign != 'left' )
$halign = $this->title->halign;
if( $this->title_adjust=="high" )
$this->title->Pos($x,$this->img->top_margin,$halign,"top");
elseif($this->title_adjust=="middle" || $this->title_adjust=="center")
$this->title->Pos($x,($this->img->height-$this->img->top_margin-$this->img->bottom_margin)/2+$this->img->top_margin,$halign,"center");
elseif($this->title_adjust=="low")
$this->title->Pos($x,$this->img->height-$this->img->bottom_margin,$halign,"bottom");
else
JpGraphError::RaiseL(25061,$this->title_adjust);//('Unknown alignment specified for Y-axis title. ('.$this->title_adjust.')');
}
$this->scale->ticks->Stroke($this->img,$this->scale,$pos);
if( $aStrokeLabels ) {
if( !$this->hide_labels )
$this->StrokeLabels($pos);
$this->title->Stroke($this->img);
}
}
 
//---------------
// PRIVATE METHODS
// Draw all the tick labels on major tick marks
function StrokeLabels($aPos,$aMinor=false,$aAbsLabel=false) {
 
$this->img->SetColor($this->label_color);
$this->img->SetFont($this->font_family,$this->font_style,$this->font_size);
$yoff=$this->img->GetFontHeight()/2;
 
// Only draw labels at major tick marks
$nbr = count($this->scale->ticks->maj_ticks_label);
 
// We have the option to not-display the very first mark
// (Usefull when the first label might interfere with another
// axis.)
$i = $this->show_first_label ? 0 : 1 ;
if( !$this->show_last_label ) --$nbr;
// Now run through all labels making sure we don't overshoot the end
// of the scale.
$ncolor=0;
if( isset($this->ticks_label_colors) )
$ncolor=count($this->ticks_label_colors);
while( $i<$nbr ) {
// $tpos holds the absolute text position for the label
$tpos=$this->scale->ticks->maj_ticklabels_pos[$i];
 
// Note. the $limit is only used for the x axis since we
// might otherwise overshoot if the scale has been centered
// This is due to us "loosing" the last tick mark if we center.
if( $this->scale->type=="x" && $tpos > $this->img->width-$this->img->right_margin+1 ) {
return;
}
// we only draw every $label_step label
if( ($i % $this->label_step)==0 ) {
 
// Set specific label color if specified
if( $ncolor > 0 )
$this->img->SetColor($this->ticks_label_colors[$i % $ncolor]);
// If the label has been specified use that and in other case
// just label the mark with the actual scale value
$m=$this->scale->ticks->GetMajor();
// ticks_label has an entry for each data point and is the array
// that holds the labels set by the user. If the user hasn't
// specified any values we use whats in the automatically asigned
// labels in the maj_ticks_label
if( isset($this->ticks_label[$i*$m]) )
$label=$this->ticks_label[$i*$m];
else {
if( $aAbsLabel )
$label=abs($this->scale->ticks->maj_ticks_label[$i]);
else
$label=$this->scale->ticks->maj_ticks_label[$i];
if( $this->scale->textscale && $this->scale->ticks->label_formfunc == '' ) {
++$label;
}
}
//if( $this->hide_zero_label && $label==0.0 ) {
// ++$i;
// continue;
//}
if( $this->scale->type == "x" ) {
if( $this->labelPos == SIDE_DOWN ) {
if( $this->label_angle==0 || $this->label_angle==90 ) {
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign('center','top');
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
}
else {
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign("right","top");
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
}
 
$this->img->StrokeText($tpos,$aPos+$this->tick_label_margin+1,$label,
$this->label_angle,$this->label_para_align);
}
else {
if( $this->label_angle==0 || $this->label_angle==90 ) {
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign("center","bottom");
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
}
else {
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign("right","bottom");
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
}
$this->img->StrokeText($tpos,$aPos-$this->tick_label_margin-1,$label,
$this->label_angle,$this->label_para_align);
}
}
else {
// scale->type == "y"
//if( $this->label_angle!=0 )
//JpGraphError::Raise(" Labels at an angle are not supported on Y-axis");
if( $this->labelPos == SIDE_LEFT ) { // To the left of y-axis
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign("right","center");
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
$this->img->StrokeText($aPos-$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align);
}
else { // To the right of the y-axis
if( $this->label_halign=='' && $this->label_valign=='')
$this->img->SetTextAlign("left","center");
else
$this->img->SetTextAlign($this->label_halign,$this->label_valign);
$this->img->StrokeText($aPos+$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align);
}
}
}
++$i;
}
}
 
} // Class
 
//===================================================
// CLASS Ticks
// Description: Abstract base class for drawing linear and logarithmic
// tick marks on axis
//===================================================
class Ticks {
var $minor_abs_size=3, $major_abs_size=5;
var $direction=1; // Should ticks be in(=1) the plot area or outside (=-1)?
var $scale;
var $is_set=false;
var $precision;
var $supress_zerolabel=false,$supress_first=false;
var $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false;
var $mincolor="",$majcolor="";
var $weight=1;
var $label_formatstr=''; // C-style format string to use for labels
var $label_formfunc='';
var $label_dateformatstr='';
var $label_usedateformat=FALSE;
 
 
//---------------
// CONSTRUCTOR
function Ticks(&$aScale) {
$this->scale=&$aScale;
$this->precision = -1;
}
 
//---------------
// PUBLIC METHODS
// Set format string for automatic labels
function SetLabelFormat($aFormatString,$aDate=FALSE) {
$this->label_formatstr=$aFormatString;
$this->label_usedateformat=$aDate;
}
 
function SetLabelDateFormat($aFormatString) {
$this->label_dateformatstr=$aFormatString;
}
function SetFormatCallback($aCallbackFuncName) {
$this->label_formfunc = $aCallbackFuncName;
}
// Don't display the first zero label
function SupressZeroLabel($aFlag=true) {
$this->supress_zerolabel=$aFlag;
}
// Don't display minor tick marks
function SupressMinorTickMarks($aHide=true) {
$this->supress_minor_tickmarks=$aHide;
}
// Don't display major tick marks
function SupressTickMarks($aHide=true) {
$this->supress_tickmarks=$aHide;
}
// Hide the first tick mark
function SupressFirst($aHide=true) {
$this->supress_first=$aHide;
}
// Hide the last tick mark
function SupressLast($aHide=true) {
$this->supress_last=$aHide;
}
 
// Size (in pixels) of minor tick marks
function GetMinTickAbsSize() {
return $this->minor_abs_size;
}
// Size (in pixels) of major tick marks
function GetMajTickAbsSize() {
return $this->major_abs_size;
}
function SetSize($aMajSize,$aMinSize=3) {
$this->major_abs_size = $aMajSize;
$this->minor_abs_size = $aMinSize;
}
 
// Have the ticks been specified
function IsSpecified() {
return $this->is_set;
}
// Set the distance between major and minor tick marks
function Set($aMaj,$aMin) {
// "Virtual method"
// Should be implemented by the concrete subclass
// if any action is wanted.
}
// Specify number of decimals in automatic labels
// Deprecated from 1.4. Use SetFormatString() instead
function SetPrecision($aPrecision) {
if( ERR_DEPRECATED )
JpGraphError::RaiseL(25063);//('Ticks::SetPrecision() is deprecated. Use Ticks::SetLabelFormat() (or Ticks::SetFormatCallback()) instead');
$this->precision=$aPrecision;
}
 
function SetSide($aSide) {
$this->direction=$aSide;
}
// Which side of the axis should the ticks be on
function SetDirection($aSide=SIDE_RIGHT) {
$this->direction=$aSide;
}
// Set colors for major and minor tick marks
function SetMarkColor($aMajorColor,$aMinorColor="") {
$this->SetColor($aMajorColor,$aMinorColor);
}
function SetColor($aMajorColor,$aMinorColor="") {
$this->majcolor=$aMajorColor;
// If not specified use same as major
if( $aMinorColor=="" )
$this->mincolor=$aMajorColor;
else
$this->mincolor=$aMinorColor;
}
function SetWeight($aWeight) {
$this->weight=$aWeight;
}
} // Class
 
//===================================================
// CLASS LinearTicks
// Description: Draw linear ticks on axis
//===================================================
class LinearTicks extends Ticks {
var $minor_step=1, $major_step=2;
var $xlabel_offset=0,$xtick_offset=0;
var $label_offset=0; // What offset should the displayed label have
// i.e should we display 0,1,2 or 1,2,3,4 or 2,3,4 etc
var $text_label_start=0;
var $iManualTickPos = NULL, $iManualMinTickPos = NULL, $iManualTickLabels = NULL;
var $maj_ticks_pos = array(), $maj_ticklabels_pos = array(),
$ticks_pos = array(), $maj_ticks_label = array();
var $iAdjustForDST = false; // If a date falls within the DST period add one hour to the diaplyed time
 
//---------------
// CONSTRUCTOR
function LinearTicks() {
$this->precision = -1;
}
 
//---------------
// 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::RaiseL(25064);
//(" Minor or major step size is 0. Check that you haven't got an accidental SetTextTicks(0) in your code. 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 SetMajTickPositions($aMajPos,$aLabels=NULL) {
$this->SetTickPositions($aMajPos,NULL,$aLabels);
}
 
function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) {
if( !is_array($aMajPos) || ($aMinPos!==NULL && !is_array($aMinPos)) ) {
JpGraphError::RaiseL(25065);//('Tick positions must be specifued as an array()');
return;
}
$n=count($aMajPos);
if( is_array($aLabels) && (count($aLabels) != $n) ) {
JpGraphError::RaiseL(25066);//('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.');
return;
}
$this->iManualTickPos = $aMajPos;
$this->iManualMinTickPos = $aMinPos;
$this->iManualTickLabels = $aLabels;
}
 
// Specify all the tick positions manually and possible also the exact labels
function _doManualTickPos($aScale) {
$n=count($this->iManualTickPos);
$m=count($this->iManualMinTickPos);
$doLbl=count($this->iManualTickLabels) > 0;
 
$this->maj_ticks_pos = array();
$this->maj_ticklabels_pos = array();
$this->ticks_pos = array();
 
// Now loop through the supplied positions and translate them to screen coordinates
// and store them in the maj_label_positions
$minScale = $aScale->scale[0];
$maxScale = $aScale->scale[1];
$j=0;
for($i=0; $i < $n ; ++$i ) {
// First make sure that the first tick is not lower than the lower scale value
if( !isset($this->iManualTickPos[$i]) ||
$this->iManualTickPos[$i] < $minScale || $this->iManualTickPos[$i] > $maxScale) {
continue;
}
 
 
$this->maj_ticks_pos[$j] = $aScale->Translate($this->iManualTickPos[$i]);
$this->maj_ticklabels_pos[$j] = $this->maj_ticks_pos[$j];
 
// Set the minor tick marks the same as major if not specified
if( $m <= 0 ) {
$this->ticks_pos[$j] = $this->maj_ticks_pos[$j];
}
 
if( $doLbl ) {
$this->maj_ticks_label[$j] = $this->iManualTickLabels[$i];
}
else {
$this->maj_ticks_label[$j]=$this->_doLabelFormat($this->iManualTickPos[$i],$i,$n);
}
++$j;
}
 
// Some sanity check
if( count($this->maj_ticks_pos) < 2 ) {
JpGraphError::RaiseL(25067);//('Your manually specified scale and ticks is not correct. The scale seems to be too small to hold any of the specified tickl marks.');
}
 
// Setup the minor tick marks
$j=0;
for($i=0; $i < $m; ++$i ) {
if( empty($this->iManualMinTickPos[$i]) ||
$this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale)
continue;
$this->ticks_pos[$j] = $aScale->Translate($this->iManualMinTickPos[$i]);
++$j;
}
}
 
function _doAutoTickPos($aScale) {
$maj_step_abs = $aScale->scale_factor*$this->major_step;
$min_step_abs = $aScale->scale_factor*$this->minor_step;
 
if( $min_step_abs==0 || $maj_step_abs==0 ) {
JpGraphError::RaiseL(25068);//("A plot has an illegal scale. This could for example be that you are trying to use text autoscaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only '-' or 'x')");
}
// We need to make this an int since comparing it below
// with the result from round() can give wrong result, such that
// (40 < 40) == TRUE !!!
$limit = (int)$aScale->scale_abs[1];
 
if( $aScale->textscale ) {
// This can only be true for a X-scale (horizontal)
// Define ticks for a text scale. This is slightly different from a
// normal linear type of scale since the position might be adjusted
// and the labels start at on
$label = (float)$aScale->GetMinVal()+$this->text_label_start+$this->label_offset;
$start_abs=$aScale->scale_factor*$this->text_label_start;
$nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1;
$x = $aScale->scale_abs[0]+$start_abs+$this->xlabel_offset*$min_step_abs;
for( $i=0; $label <= $aScale->GetMaxVal()+$this->label_offset; ++$i ) {
// Apply format to label
$this->maj_ticks_label[$i]=$this->_doLabelFormat($label,$i,$nbrmajticks);
$label+=$this->major_step;
 
// The x-position of the tick marks can be different from the labels.
// Note that we record the tick position (not the label) so that the grid
// happen upon tick marks and not labels.
$xtick=$aScale->scale_abs[0]+$start_abs+$this->xtick_offset*$min_step_abs+$i*$maj_step_abs;
$this->maj_ticks_pos[$i]=$xtick;
$this->maj_ticklabels_pos[$i] = round($x);
$x += $maj_step_abs;
 
}
}
else {
$label = $aScale->GetMinVal();
$abs_pos = $aScale->scale_abs[0];
$j=0; $i=0;
$step = round($maj_step_abs/$min_step_abs);
if( $aScale->type == "x" ) {
// For a normal linear type of scale the major ticks will always be multiples
// of the minor ticks. In order to avoid any rounding issues the major ticks are
// defined as every "step" minor ticks and not calculated separately
$nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1;
while( round($abs_pos) <= $limit ) {
$this->ticks_pos[] = round($abs_pos);
$this->ticks_label[] = $label;
if( $step == 0 || $i % $step == 0 && $j < $nbrmajticks ) {
$this->maj_ticks_pos[$j] = round($abs_pos);
$this->maj_ticklabels_pos[$j] = round($abs_pos);
$this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks);
++$j;
}
++$i;
$abs_pos += $min_step_abs;
$label+=$this->minor_step;
}
}
elseif( $aScale->type == "y" ) {
$nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal())/$this->major_step)+1;
while( round($abs_pos) >= $limit ) {
$this->ticks_pos[$i] = round($abs_pos);
$this->ticks_label[$i]=$label;
if( $step == 0 || $i % $step == 0 && $j < $nbrmajticks ) {
$this->maj_ticks_pos[$j] = round($abs_pos);
$this->maj_ticklabels_pos[$j] = round($abs_pos);
$this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks);
++$j;
}
++$i;
$abs_pos += $min_step_abs;
$label += $this->minor_step;
}
}
}
}
 
function AdjustForDST($aFlg=true) {
$this->iAdjustForDST = $aFlg;
}
 
 
function _doLabelFormat($aVal,$aIdx,$aNbrTicks) {
 
// If precision hasn't been specified set it to a sensible value
if( $this->precision==-1 ) {
$t = log10($this->minor_step);
if( $t > 0 )
$precision = 0;
else
$precision = -floor($t);
}
else
$precision = $this->precision;
 
if( $this->label_formfunc != '' ) {
$f=$this->label_formfunc;
$l = call_user_func($f,$aVal);
}
elseif( $this->label_formatstr != '' || $this->label_dateformatstr != '' ) {
if( $this->label_usedateformat ) {
// Adjust the value to take daylight savings into account
if (date("I",$aVal)==1 && $this->iAdjustForDST ) // DST
$aVal+=3600;
$l = date($this->label_formatstr,$aVal);
if( $this->label_formatstr == 'W' ) {
// If we use week formatting then add a single 'w' in front of the
// week number to differentiate it from dates
$l = 'w'.$l;
}
}
else {
if( $this->label_dateformatstr !== '' ) {
// Adjust the value to take daylight savings into account
if (date("I",$aVal)==1 && $this->iAdjustForDST ) // DST
$aVal+=3600;
$l = date($this->label_dateformatstr,$aVal);
if( $this->label_formatstr == 'W' ) {
// If we use week formatting then add a single 'w' in front of the
// week number to differentiate it from dates
$l = 'w'.$l;
}
}
else
$l = sprintf($this->label_formatstr,$aVal);
}
}
else {
$l = sprintf('%01.'.$precision.'f',round($aVal,$precision));
}
if( ($this->supress_zerolabel && $l==0) || ($this->supress_first && $aIdx==0) ||
($this->supress_last && $aIdx==$aNbrTicks-1) ) {
$l='';
}
return $l;
}
 
// Stroke ticks on either X or Y axis
function _StrokeTicks(&$aImg,$aScale,$aPos) {
$hor = $aScale->type == 'x';
$aImg->SetLineWeight($this->weight);
 
// We need to make this an int since comparing it below
// with the result from round() can give wrong result, such that
// (40 < 40) == TRUE !!!
$limit = (int)$aScale->scale_abs[1];
// A text scale doesn't have any minor ticks
if( !$aScale->textscale ) {
// Stroke minor ticks
$yu = $aPos - $this->direction*$this->GetMinTickAbsSize();
$xr = $aPos + $this->direction*$this->GetMinTickAbsSize();
$n = count($this->ticks_pos);
for($i=0; $i < $n; ++$i ) {
if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor);
if( $hor ) {
//if( $this->ticks_pos[$i] <= $limit )
$aImg->Line($this->ticks_pos[$i],$aPos,$this->ticks_pos[$i],$yu);
}
else {
//if( $this->ticks_pos[$i] >= $limit )
$aImg->Line($aPos,$this->ticks_pos[$i],$xr,$this->ticks_pos[$i]);
}
if( $this->mincolor!="" ) $aImg->PopColor();
}
}
}
 
// Stroke major ticks
$yu = $aPos - $this->direction*$this->GetMajTickAbsSize();
$xr = $aPos + $this->direction*$this->GetMajTickAbsSize();
$nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1;
$n = count($this->maj_ticks_pos);
for($i=0; $i < $n ; ++$i ) {
if(!($this->xtick_offset > 0 && $i==$nbrmajticks-1) && !$this->supress_tickmarks) {
if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor);
if( $hor ) {
//if( $this->maj_ticks_pos[$i] <= $limit )
$aImg->Line($this->maj_ticks_pos[$i],$aPos,$this->maj_ticks_pos[$i],$yu);
}
else {
//if( $this->maj_ticks_pos[$i] >= $limit )
$aImg->Line($aPos,$this->maj_ticks_pos[$i],$xr,$this->maj_ticks_pos[$i]);
}
if( $this->majcolor!="" ) $aImg->PopColor();
}
}
}
 
// Draw linear ticks
function Stroke(&$aImg,$aScale,$aPos) {
if( $this->iManualTickPos != NULL )
$this->_doManualTickPos($aScale);
else
$this->_doAutoTickPos($aScale);
$this->_StrokeTicks($aImg,$aScale,$aPos, $aScale->type == 'x' );
}
 
//---------------
// PRIVATE METHODS
// Spoecify the offset of the displayed tick mark with the tick "space"
// Legal values for $o is [0,1] used to adjust where the tick marks and label
// should be positioned within the major tick-size
// $lo specifies the label offset and $to specifies the tick offset
// this comes in handy for example in bar graphs where we wont no offset for the
// tick but have the labels displayed halfway under the bars.
function SetXLabelOffset($aLabelOff,$aTickOff=-1) {
$this->xlabel_offset=$aLabelOff;
if( $aTickOff==-1 ) // Same as label offset
$this->xtick_offset=$aLabelOff;
else
$this->xtick_offset=$aTickOff;
if( $aLabelOff>0 )
$this->SupressLast(); // The last tick wont fit
}
 
// Which tick label should we start with?
function SetTextLabelStart($aTextLabelOff) {
$this->text_label_start=$aTextLabelOff;
}
} // Class
 
//===================================================
// CLASS LinearScale
// Description: Handle linear scaling between screen and world
//===================================================
class LinearScale {
var $scale=array(0,0);
var $scale_abs=array(0,0);
var $scale_factor; // Scale factor between world and screen
var $world_size; // Plot area size in world coordinates
var $world_abs_size; // Plot area size in pixels
var $off; // Offset between image edge and plot area
var $type; // is this x or y scale ?
var $ticks=null; // Store ticks
var $text_scale_off = 0;
var $autoscale_min=false; // Forced minimum value, auto determine max
var $autoscale_max=false; // Forced maximum value, auto determine min
var $gracetop=0,$gracebottom=0;
var $intscale=false; // Restrict autoscale to integers
var $textscale=false; // Just a flag to let the Plot class find out if
// we are a textscale or not. This is a cludge since
// this ionformatyion is availabale in Graph::axtype but
// we don't have access to the graph object in the Plots
// stroke method. So we let graph store the status here
// when the linear scale is created. A real cludge...
var $auto_ticks=false; // When using manual scale should the ticks be automatically set?
var $name = 'lin';
//---------------
// CONSTRUCTOR
function LinearScale($aMin=0,$aMax=0,$aType="y") {
assert($aType=="x" || $aType=="y" );
assert($aMin<=$aMax);
$this->type=$aType;
$this->scale=array($aMin,$aMax);
$this->world_size=$aMax-$aMin;
$this->ticks = new LinearTicks();
}
 
//---------------
// PUBLIC METHODS
// Check if scale is set or if we should autoscale
// We should do this is either scale or ticks has not been set
function IsSpecified() {
if( $this->GetMinVal()==$this->GetMaxVal() ) { // Scale not set
return false;
}
return true;
}
// Set the minimum data value when the autoscaling is used.
// Usefull if you want a fix minimum (like 0) but have an
// automatic maximum
function SetAutoMin($aMin) {
$this->autoscale_min=$aMin;
}
 
// Set the minimum data value when the autoscaling is used.
// Usefull if you want a fix minimum (like 0) but have an
// automatic maximum
function SetAutoMax($aMax) {
$this->autoscale_max=$aMax;
}
 
// If the user manually specifies a scale should the ticks
// still be set automatically?
function SetAutoTicks($aFlag=true) {
$this->auto_ticks = $aFlag;
}
 
// Specify scale "grace" value (top and bottom)
function SetGrace($aGraceTop,$aGraceBottom=0) {
if( $aGraceTop<0 || $aGraceBottom < 0 )
JpGraphError::RaiseL(25069);//(" Grace must be larger then 0");
$this->gracetop=$aGraceTop;
$this->gracebottom=$aGraceBottom;
}
// Get the minimum value in the scale
function GetMinVal() {
return $this->scale[0];
}
// get maximum value for scale
function GetMaxVal() {
return $this->scale[1];
}
// Specify a new min/max value for sclae
function Update(&$aImg,$aMin,$aMax) {
$this->scale=array($aMin,$aMax);
$this->world_size=$aMax-$aMin;
$this->InitConstants($aImg);
}
// Translate between world and screen
function Translate($aCoord) {
if( !is_numeric($aCoord) ) {
if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' )
JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.');
return 0;
}
else {
return $this->off + ($aCoord - $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($aCoord) {
if( !is_numeric($aCoord) ) {
if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' )
JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.');
return 0;
}
else {
return ($aCoord - $this->scale[0]) * $this->scale_factor;
}
}
// Restrict autoscaling to only use integers
function SetIntScale($aIntScale=true) {
$this->intscale=$aIntScale;
}
// Calculate an integer autoscale
function IntAutoScale(&$img,$min,$max,$maxsteps,$majend=true) {
// Make sure limits are integers
$min=floor($min);
$max=ceil($max);
if( abs($min-$max)==0 ) {
--$min; ++$max;
}
$maxsteps = floor($maxsteps);
$gracetop=round(($this->gracetop/100.0)*abs($max-$min));
$gracebottom=round(($this->gracebottom/100.0)*abs($max-$min));
if( is_numeric($this->autoscale_min) ) {
$min = ceil($this->autoscale_min);
if( $min >= $max ) {
JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.');
}
}
 
if( is_numeric($this->autoscale_max) ) {
$max = ceil($this->autoscale_max);
if( $min >= $max ) {
JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.');
}
}
 
if( abs($min-$max ) == 0 ) {
++$max;
--$min;
}
$min -= $gracebottom;
$max += $gracetop;
 
// First get tickmarks as multiples of 1, 10, ...
if( $majend ) {
list($num1steps,$adj1min,$adj1max,$maj1step) =
$this->IntCalcTicks($maxsteps,$min,$max,1);
}
else {
$adj1min = $min;
$adj1max = $max;
list($num1steps,$maj1step) =
$this->IntCalcTicksFreeze($maxsteps,$min,$max,1);
}
 
if( abs($min-$max) > 2 ) {
// Then get tick marks as 2:s 2, 20, ...
if( $majend ) {
list($num2steps,$adj2min,$adj2max,$maj2step) =
$this->IntCalcTicks($maxsteps,$min,$max,5);
}
else {
$adj2min = $min;
$adj2max = $max;
list($num2steps,$maj2step) =
$this->IntCalcTicksFreeze($maxsteps,$min,$max,5);
}
}
else {
$num2steps = 10000; // Dummy high value so we don't choose this
}
if( abs($min-$max) > 5 ) {
// Then get tickmarks as 5:s 5, 50, 500, ...
if( $majend ) {
list($num5steps,$adj5min,$adj5max,$maj5step) =
$this->IntCalcTicks($maxsteps,$min,$max,2);
}
else {
$adj5min = $min;
$adj5max = $max;
list($num5steps,$maj5step) =
$this->IntCalcTicksFreeze($maxsteps,$min,$max,2);
}
}
else {
$num5steps = 10000; // Dummy high value so we don't choose this
}
// Check to see whichof 1:s, 2:s or 5:s fit better with
// the requested number of major ticks
$match1=abs($num1steps-$maxsteps);
$match2=abs($num2steps-$maxsteps);
if( !empty($maj5step) && $maj5step > 1 )
$match5=abs($num5steps-$maxsteps);
else
$match5=10000; // Dummy high value
// Compare these three values and see which is the closest match
// We use a 0.6 weight to gravitate towards multiple of 5:s
if( $match1 < $match2 ) {
if( $match1 < $match5 )
$r=1;
else
$r=3;
}
else {
if( $match2 < $match5 )
$r=2;
else
$r=3;
}
// Minsteps are always the same as maxsteps for integer scale
switch( $r ) {
case 1:
$this->ticks->Set($maj1step,$maj1step);
$this->Update($img,$adj1min,$adj1max);
break;
case 2:
$this->ticks->Set($maj2step,$maj2step);
$this->Update($img,$adj2min,$adj2max);
break;
case 3:
$this->ticks->Set($maj5step,$maj5step);
$this->Update($img,$adj5min,$adj5max);
break;
default:
JpGraphError::RaiseL(25073,$r);//('Internal error. Integer scale algorithm comparison out of bound (r=$r)');
}
}
// Calculate autoscale. Used if user hasn't given a scale and ticks
// $maxsteps is the maximum number of major tickmarks allowed.
function AutoScale(&$img,$min,$max,$maxsteps,$majend=true) {
if( $this->intscale ) {
$this->IntAutoScale($img,$min,$max,$maxsteps,$majend);
return;
}
if( abs($min-$max) < 0.00001 ) {
// We need some difference to be able to autoscale
// make it 5% above and 5% below value
if( $min==0 && $max==0 ) { // Special case
$min=-1; $max=1;
}
else {
$delta = (abs($max)+abs($min))*0.005;
$min -= $delta;
$max += $delta;
}
}
$gracetop=($this->gracetop/100.0)*abs($max-$min);
$gracebottom=($this->gracebottom/100.0)*abs($max-$min);
if( is_numeric($this->autoscale_min) ) {
$min = $this->autoscale_min;
if( $min >= $max ) {
JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.');
}
if( abs($min-$max ) < 0.00001 )
$max *= 1.2;
}
 
if( is_numeric($this->autoscale_max) ) {
$max = $this->autoscale_max;
if( $min >= $max ) {
JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.');
}
if( abs($min-$max ) < 0.00001 )
$min *= 0.8;
}
 
$min -= $gracebottom;
$max += $gracetop;
 
// First get tickmarks as multiples of 0.1, 1, 10, ...
if( $majend ) {
list($num1steps,$adj1min,$adj1max,$min1step,$maj1step) =
$this->CalcTicks($maxsteps,$min,$max,1,2);
}
else {
$adj1min=$min;
$adj1max=$max;
list($num1steps,$min1step,$maj1step) =
$this->CalcTicksFreeze($maxsteps,$min,$max,1,2,false);
}
// Then get tick marks as 2:s 0.2, 2, 20, ...
if( $majend ) {
list($num2steps,$adj2min,$adj2max,$min2step,$maj2step) =
$this->CalcTicks($maxsteps,$min,$max,5,2);
}
else {
$adj2min=$min;
$adj2max=$max;
list($num2steps,$min2step,$maj2step) =
$this->CalcTicksFreeze($maxsteps,$min,$max,5,2,false);
}
// Then get tickmarks as 5:s 0.05, 0.5, 5, 50, ...
if( $majend ) {
list($num5steps,$adj5min,$adj5max,$min5step,$maj5step) =
$this->CalcTicks($maxsteps,$min,$max,2,5);
}
else {
$adj5min=$min;
$adj5max=$max;
list($num5steps,$min5step,$maj5step) =
$this->CalcTicksFreeze($maxsteps,$min,$max,2,5,false);
}
 
// Check to see whichof 1:s, 2:s or 5:s fit better with
// the requested number of major ticks
$match1=abs($num1steps-$maxsteps);
$match2=abs($num2steps-$maxsteps);
$match5=abs($num5steps-$maxsteps);
// Compare these three values and see which is the closest match
// We use a 0.8 weight to gravitate towards multiple of 5:s
$r=$this->MatchMin3($match1,$match2,$match5,0.8);
switch( $r ) {
case 1:
$this->Update($img,$adj1min,$adj1max);
$this->ticks->Set($maj1step,$min1step);
break;
case 2:
$this->Update($img,$adj2min,$adj2max);
$this->ticks->Set($maj2step,$min2step);
break;
case 3:
$this->Update($img,$adj5min,$adj5max);
$this->ticks->Set($maj5step,$min5step);
break;
}
}
 
//---------------
// PRIVATE METHODS
 
// This method recalculates all constants that are depending on the
// margins in the image. If the margins in the image are changed
// this method should be called for every scale that is registred with
// that image. Should really be installed as an observer of that image.
function InitConstants(&$img) {
if( $this->type=="x" ) {
$this->world_abs_size=$img->width - $img->left_margin - $img->right_margin;
$this->off=$img->left_margin;
$this->scale_factor = 0;
if( $this->world_size > 0 )
$this->scale_factor=$this->world_abs_size/($this->world_size*1.0);
}
else { // y scale
$this->world_abs_size=$img->height - $img->top_margin - $img->bottom_margin;
$this->off=$img->top_margin+$this->world_abs_size;
$this->scale_factor = 0;
if( $this->world_size > 0 ) {
$this->scale_factor=-$this->world_abs_size/($this->world_size*1.0);
}
}
$size = $this->world_size * $this->scale_factor;
$this->scale_abs=array($this->off,$this->off + $size);
}
// Initialize the conversion constants for this scale
// This tries to pre-calculate as much as possible to speed up the
// actual conversion (with Translate()) later on
// $start =scale start in absolute pixels (for x-scale this is an y-position
// and for an y-scale this is an x-position
// $len =absolute length in pixels of scale
function SetConstants($aStart,$aLen) {
$this->world_abs_size=$aLen;
$this->off=$aStart;
if( $this->world_size<=0 ) {
// This should never ever happen !!
JpGraphError::RaiseL(25074);
//("You have unfortunately stumbled upon a bug in JpGraph. It seems like the scale range is ".$this->world_size." [for ".$this->type." scale] <br> Please report Bug #01 to jpgraph@aditus.nu and include the script that gave this error. This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the autoscaling to fail.");
 
}
// scale_factor = number of pixels per world unit
$this->scale_factor=$this->world_abs_size/($this->world_size*1.0);
// scale_abs = start and end points of scale in absolute pixels
$this->scale_abs=array($this->off,$this->off+$this->world_size*$this->scale_factor);
}
// Calculate number of ticks steps with a specific division
// $a is the divisor of 10**x to generate the first maj tick intervall
// $a=1, $b=2 give major ticks with multiple of 10, ...,0.1,1,10,...
// $a=5, $b=2 give major ticks with multiple of 2:s ...,0.2,2,20,...
// $a=2, $b=5 give major ticks with multiple of 5:s ...,0.5,5,50,...
// We return a vector of
// [$numsteps,$adjmin,$adjmax,$minstep,$majstep]
// If $majend==true then the first and last marks on the axis will be major
// labeled tick marks otherwise it will be adjusted to the closest min tick mark
function CalcTicks($maxsteps,$min,$max,$a,$b,$majend=true) {
$diff=$max-$min;
if( $diff==0 )
$ld=0;
else
$ld=floor(log10($diff));
 
// Gravitate min towards zero if we are close
if( $min>0 && $min < pow(10,$ld) ) $min=0;
//$majstep=pow(10,$ld-1)/$a;
$majstep=pow(10,$ld)/$a;
$minstep=$majstep/$b;
$adjmax=ceil($max/$minstep)*$minstep;
$adjmin=floor($min/$minstep)*$minstep;
$adjdiff = $adjmax-$adjmin;
$numsteps=$adjdiff/$majstep;
while( $numsteps>$maxsteps ) {
$majstep=pow(10,$ld)/$a;
$numsteps=$adjdiff/$majstep;
++$ld;
}
 
$minstep=$majstep/$b;
$adjmin=floor($min/$minstep)*$minstep;
$adjdiff = $adjmax-$adjmin;
if( $majend ) {
$adjmin = floor($min/$majstep)*$majstep;
$adjdiff = $adjmax-$adjmin;
$adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin;
}
else
$adjmax=ceil($max/$minstep)*$minstep;
 
return array($numsteps,$adjmin,$adjmax,$minstep,$majstep);
}
 
function CalcTicksFreeze($maxsteps,$min,$max,$a,$b) {
// Same as CalcTicks but don't adjust min/max values
$diff=$max-$min;
if( $diff==0 )
$ld=0;
else
$ld=floor(log10($diff));
 
//$majstep=pow(10,$ld-1)/$a;
$majstep=pow(10,$ld)/$a;
$minstep=$majstep/$b;
$numsteps=floor($diff/$majstep);
while( $numsteps > $maxsteps ) {
$majstep=pow(10,$ld)/$a;
$numsteps=floor($diff/$majstep);
++$ld;
}
$minstep=$majstep/$b;
return array($numsteps,$minstep,$majstep);
}
 
function IntCalcTicks($maxsteps,$min,$max,$a,$majend=true) {
$diff=$max-$min;
if( $diff==0 )
JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.');
else
$ld=floor(log10($diff));
// Gravitate min towards zero if we are close
if( $min>0 && $min < pow(10,$ld) ) $min=0;
if( $ld == 0 ) $ld=1;
if( $a == 1 )
$majstep = 1;
else
$majstep=pow(10,$ld)/$a;
$adjmax=ceil($max/$majstep)*$majstep;
 
$adjmin=floor($min/$majstep)*$majstep;
$adjdiff = $adjmax-$adjmin;
$numsteps=$adjdiff/$majstep;
while( $numsteps>$maxsteps ) {
$majstep=pow(10,$ld)/$a;
$numsteps=$adjdiff/$majstep;
++$ld;
}
$adjmin=floor($min/$majstep)*$majstep;
$adjdiff = $adjmax-$adjmin;
if( $majend ) {
$adjmin = floor($min/$majstep)*$majstep;
$adjdiff = $adjmax-$adjmin;
$adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin;
}
else
$adjmax=ceil($max/$majstep)*$majstep;
return array($numsteps,$adjmin,$adjmax,$majstep);
}
 
 
function IntCalcTicksFreeze($maxsteps,$min,$max,$a) {
// Same as IntCalcTick but don't change min/max values
$diff=$max-$min;
if( $diff==0 )
JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.');
else
$ld=floor(log10($diff));
if( $ld == 0 ) $ld=1;
if( $a == 1 )
$majstep = 1;
else
$majstep=pow(10,$ld)/$a;
 
$numsteps=floor($diff/$majstep);
while( $numsteps > $maxsteps ) {
$majstep=pow(10,$ld)/$a;
$numsteps=floor($diff/$majstep);
++$ld;
}
return array($numsteps,$majstep);
}
 
 
// Determine the minimum of three values witha weight for last value
function MatchMin3($a,$b,$c,$weight) {
if( $a < $b ) {
if( $a < ($c*$weight) )
return 1; // $a smallest
else
return 3; // $c smallest
}
elseif( $b < ($c*$weight) )
return 2; // $b smallest
return 3; // $c smallest
}
} // Class
//===================================================
// CLASS ImgStreamCache
// Description: Handle caching of graphs to files
//===================================================
class ImgStreamCache {
var $cache_dir;
var $img=null;
var $timeout=0; // Infinite timeout
//---------------
// CONSTRUCTOR
function ImgStreamCache(&$aImg, $aCacheDir=CACHE_DIR) {
$this->img = &$aImg;
$this->cache_dir = $aCacheDir;
}
 
//---------------
// PUBLIC METHODS
 
// Specify a timeout (in minutes) for the file. If the file is older then the
// timeout value it will be overwritten with a newer version.
// If timeout is set to 0 this is the same as infinite large timeout and if
// timeout is set to -1 this is the same as infinite small timeout
function SetTimeout($aTimeout) {
$this->timeout=$aTimeout;
}
// Output image to browser and also write it to the cache
function PutAndStream(&$aImage,$aCacheFileName,$aInline,$aStrokeFileName) {
// Some debugging code to brand the image with numbe of colors
// used
GLOBAL $gJpgBrandTiming;
if( $gJpgBrandTiming ) {
global $tim;
$t=$tim->Pop()/1000.0;
$c=$aImage->SetColor("black");
$t=sprintf(BRAND_TIME_FORMAT,round($t,3));
imagestring($this->img->img,2,5,$this->img->height-20,$t,$c);
}
 
// Check if we should stroke the image to an arbitrary file
if( _FORCE_IMGTOFILE ) {
$aStrokeFileName = _FORCE_IMGDIR.GenImgName();
}
 
if( $aStrokeFileName!="" ) {
if( $aStrokeFileName == "auto" )
$aStrokeFileName = GenImgName();
if( file_exists($aStrokeFileName) ) {
// Delete the old file
if( !@unlink($aStrokeFileName) )
JpGraphError::RaiseL(25111,$aStrokeFileName);//(" Can't delete cached image $aStrokeFileName. Permission problem?");
}
$aImage->Stream($aStrokeFileName);
return;
}
 
if( $aCacheFileName != "" && USE_CACHE) {
 
$aCacheFileName = $this->cache_dir . $aCacheFileName;
if( file_exists($aCacheFileName) ) {
if( !$aInline ) {
// If we are generating image off-line (just writing to the cache)
// and the file exists and is still valid (no timeout)
// then do nothing, just return.
$diff=time()-filemtime($aCacheFileName);
if( $diff < 0 )
JpGraphError::RaiseL(25112,$aCacheFileName);//(" Cached imagefile ($aCacheFileName) has file date in the future!!");
if( $this->timeout>0 && ($diff <= $this->timeout*60) )
return;
}
if( !@unlink($aCacheFileName) )
JpGraphError::RaiseL(25113,$aStrokeFileName);//(" Can't delete cached image $aStrokeFileName. Permission problem?");
$aImage->Stream($aCacheFileName);
}
else {
$this->MakeDirs(dirname($aCacheFileName));
if( !is_writeable(dirname($aCacheFileName)) ) {
JpGraphError::RaiseL(25114,$aCacheFileName);//('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.');
}
$aImage->Stream($aCacheFileName);
}
$res=true;
// Set group to specified
if( CACHE_FILE_GROUP != "" )
$res = @chgrp($aCacheFileName,CACHE_FILE_GROUP);
if( CACHE_FILE_MOD != "" )
$res = @chmod($aCacheFileName,CACHE_FILE_MOD);
if( !$res )
JpGraphError::RaiseL(25115,$aStrokeFileName);//(" Can't set permission for cached image $aStrokeFileName. Permission problem?");
$aImage->Destroy();
if( $aInline ) {
if ($fh = @fopen($aCacheFileName, "rb") ) {
$this->img->Headers();
fpassthru($fh);
return;
}
else
JpGraphError::RaiseL(25116,$aFile);//(" Cant open file from cache [$aFile]");
}
}
elseif( $aInline ) {
$this->img->Headers();
$aImage->Stream();
return;
}
}
// Check if a given image is in cache and in that case
// pass it directly on to web browser. Return false if the
// image file doesn't exist or exists but is to old
function GetAndStream($aCacheFileName) {
$aCacheFileName = $this->cache_dir.$aCacheFileName;
if ( USE_CACHE && file_exists($aCacheFileName) && $this->timeout>=0 ) {
$diff=time()-filemtime($aCacheFileName);
if( $this->timeout>0 && ($diff > $this->timeout*60) ) {
return false;
}
else {
if ($fh = @fopen($aCacheFileName, "rb")) {
$this->img->Headers();
fpassthru($fh);
return true;
}
else
JpGraphError::RaiseL(25117,$aCacheFileName);//(" Can't open cached image \"$aCacheFileName\" for reading.");
}
}
return false;
}
//---------------
// PRIVATE METHODS
// Create all necessary directories in a path
function MakeDirs($aFile) {
$dirs = array();
while ( !(file_exists($aFile)) ) {
$dirs[] = $aFile;
$aFile = dirname($aFile);
}
for ($i = sizeof($dirs)-1; $i>=0; $i--) {
if(! @mkdir($dirs[$i],0777) )
JpGraphError::RaiseL(25118,$aFile);//(" Can't create directory $aFile. Make sure PHP has write permission to this directory.");
// We also specify mode here after we have changed group.
// This is necessary if Apache user doesn't belong the
// default group and hence can't specify group permission
// in the previous mkdir() call
if( CACHE_FILE_GROUP != "" ) {
$res=true;
$res =@chgrp($dirs[$i],CACHE_FILE_GROUP);
$res &= @chmod($dirs[$i],0777);
if( !$res )
JpGraphError::RaiseL(25119,$aFile);//(" Can't set permissions for $aFile. Permission problems?");
}
}
return true;
}
} // CLASS Cache
//===================================================
// CLASS Legend
// Description: Responsible for drawing the box containing
// all the legend text for the graph
//===================================================
DEFINE('_DEFAULT_LPM_SIZE',8);
class Legend {
var $color=array(0,0,0); // Default fram color
var $fill_color=array(235,235,235); // Default fill color
var $shadow=true; // Shadow around legend "box"
var $shadow_color='gray';
var $txtcol=array();
var $mark_abs_hsize=_DEFAULT_LPM_SIZE, $mark_abs_vsize=_DEFAULT_LPM_SIZE;
var $xmargin=10,$ymargin=3,$shadow_width=2;
var $xlmargin=2, $ylmargin='';
var $xpos=0.05, $ypos=0.15, $xabspos=-1, $yabspos=-1;
var $halign="right", $valign="top";
var $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=10;
var $font_color='black';
var $hide=false,$layout_n=1;
var $weight=1,$frameweight=1;
var $csimareas='';
var $reverse = false ;
//---------------
// CONSTRUCTOR
function Legend() {
// Empty
}
//---------------
// PUBLIC METHODS
function Hide($aHide=true) {
$this->hide=$aHide;
}
function SetHColMargin($aXMarg) {
$this->xmargin = $aXMarg;
}
 
function SetVColMargin($aSpacing) {
$this->ymargin = $aSpacing ;
}
 
function SetLeftMargin($aXMarg) {
$this->xlmargin = $aXMarg;
}
 
// Synonym
function SetLineSpacing($aSpacing) {
$this->ymargin = $aSpacing ;
}
 
function SetShadow($aShow='gray',$aWidth=2) {
if( is_string($aShow) ) {
$this->shadow_color = $aShow;
$this->shadow=true;
}
else
$this->shadow=$aShow;
$this->shadow_width=$aWidth;
}
 
function SetMarkAbsSize($aSize) {
$this->mark_abs_vsize = $aSize ;
$this->mark_abs_hsize = $aSize ;
}
 
function SetMarkAbsVSize($aSize) {
$this->mark_abs_vsize = $aSize ;
}
 
function SetMarkAbsHSize($aSize) {
$this->mark_abs_hsize = $aSize ;
}
 
function SetLineWeight($aWeight) {
$this->weight = $aWeight;
}
 
function SetFrameWeight($aWeight) {
$this->frameweight = $aWeight;
}
function SetLayout($aDirection=LEGEND_VERT) {
$this->layout_n = $aDirection==LEGEND_VERT ? 1 : 99 ;
}
function SetColumns($aCols) {
$this->layout_n = $aCols ;
}
 
function SetReverse($f=true) {
$this->reverse = $f ;
}
 
// Set color on frame around box
function SetColor($aFontColor,$aColor='black') {
$this->font_color=$aFontColor;
$this->color=$aColor;
}
function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) {
$this->font_family = $aFamily;
$this->font_style = $aStyle;
$this->font_size = $aSize;
}
function SetPos($aX,$aY,$aHAlign="right",$aVAlign="top") {
$this->Pos($aX,$aY,$aHAlign,$aVAlign);
}
 
function SetAbsPos($aX,$aY,$aHAlign="right",$aVAlign="top") {
$this->xabspos=$aX;
$this->yabspos=$aY;
$this->halign=$aHAlign;
$this->valign=$aVAlign;
}
 
 
function Pos($aX,$aY,$aHAlign="right",$aVAlign="top") {
if( !($aX<1 && $aY<1) )
JpGraphError::RaiseL(25120);//(" Position for legend must be given as percentage in range 0-1");
$this->xpos=$aX;
$this->ypos=$aY;
$this->halign=$aHAlign;
$this->valign=$aVAlign;
}
 
function SetFillColor($aColor) {
$this->fill_color=$aColor;
}
function Add($aTxt,$aColor,$aPlotmark="",$aLinestyle=0,$csimtarget='',$csimalt='',$csimwintarget='') {
$this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt,$csimwintarget);
}
 
function GetCSIMAreas() {
return $this->csimareas;
}
function Stroke(&$aImg) {
// Constant
$fillBoxFrameWeight=1;
 
if( $this->hide ) return;
 
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
 
if( $this->reverse ) {
$this->txtcol = array_reverse($this->txtcol);
}
 
$n=count($this->txtcol);
if( $n == 0 ) return;
 
// Find out the max width and height of each column to be able
// to size the legend box.
$numcolumns = ($n > $this->layout_n ? $this->layout_n : $n);
for( $i=0; $i < $numcolumns; ++$i ) {
$colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) +
2*$this->xmargin + 2*$this->mark_abs_hsize;
$colheight[$i] = 0;
}
 
// Find our maximum height in each row
$rows = 0 ; $rowheight[0] = 0;
for( $i=0; $i < $n; ++$i ) {
$h = max($this->mark_abs_vsize,$aImg->GetTextHeight($this->txtcol[$i][0]))+$this->ymargin;
if( $i % $numcolumns == 0 ) {
$rows++;
$rowheight[$rows-1] = 0;
}
$rowheight[$rows-1] = max($rowheight[$rows-1],$h);
}
 
$abs_height = 0;
for( $i=0; $i < $rows; ++$i ) {
$abs_height += $rowheight[$i] ;
}
 
// Make sure that the height is at least as high as mark size + ymargin
$abs_height = max($abs_height,$this->mark_abs_vsize);
 
// We add 3 extra pixels height to compensate for the difficult in
// calculating font height
$abs_height += $this->ymargin+3;
// Find out the maximum width in each column
for( $i=$numcolumns; $i < $n; ++$i ) {
$colwidth[$i % $numcolumns] = max(
$aImg->GetTextWidth($this->txtcol[$i][0])+2*$this->xmargin+2*$this->mark_abs_hsize,$colwidth[$i % $numcolumns]);
}
 
// Get the total width
$mtw = 0;
for( $i=0; $i < $numcolumns; ++$i ) {
$mtw += $colwidth[$i] ;
}
 
// Find out maximum width we need for legend box
$abs_width = $mtw+$this->xlmargin;
 
if( $this->xabspos === -1 && $this->yabspos === -1 ) {
$this->xabspos = $this->xpos*$aImg->width ;
$this->yabspos = $this->ypos*$aImg->height ;
}
 
// Positioning of the legend box
if( $this->halign=="left" )
$xp = $this->xabspos;
elseif( $this->halign=="center" )
$xp = $this->xabspos - $abs_width/2;
else
$xp = $aImg->width - $this->xabspos - $abs_width;
 
$yp=$this->yabspos;
if( $this->valign=="center" )
$yp-=$abs_height/2;
elseif( $this->valign=="bottom" )
$yp-=$abs_height;
// Stroke legend box
$aImg->SetColor($this->color);
$aImg->SetLineWeight($this->frameweight);
$aImg->SetLineStyle('solid');
 
if( $this->shadow )
$aImg->ShadowRectangle($xp,$yp,$xp+$abs_width+$this->shadow_width,
$yp+$abs_height+$this->shadow_width,
$this->fill_color,$this->shadow_width,$this->shadow_color);
else {
$aImg->SetColor($this->fill_color);
$aImg->FilledRectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height);
$aImg->SetColor($this->color);
$aImg->Rectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height);
}
 
// x1,y1 is the position for the legend mark
$x1=$xp+$this->mark_abs_hsize+$this->xlmargin;
$y1=$yp + $this->ymargin;
$f2 = round($aImg->GetTextHeight('X')/2);
 
$grad = new Gradient($aImg);
$patternFactory = null;
 
// Now stroke each legend in turn
// Each plot has added the following information to the legend
// p[0] = Legend text
// p[1] = Color,
// p[2] = For markers a reference to the PlotMark object
// p[3] = For lines the line style, for gradient the negative gradient style
// p[4] = CSIM target
// p[5] = CSIM Alt text
$i = 1 ; $row = 0;
foreach($this->txtcol as $p) {
// STROKE DEBUG BOX
if( _JPG_DEBUG ) {
$aImg->SetLineWeight(1);
$aImg->SetColor('red');
$aImg->SetLineStyle('solid');
$aImg->Rectangle($xp,$y1,$xp+$abs_width,$y1+$rowheight[$row]);
}
 
$aImg->SetLineWeight($this->weight);
$x1 = round($x1); $y1=round($y1);
if ( $p[2] && $p[2]->GetType() > -1 ) {
// Make a plot mark legend
$aImg->SetColor($p[1]);
if( is_string($p[3]) || $p[3]>0 ) {
$aImg->SetLineStyle($p[3]);
$aImg->StyleLine($x1-$this->mark_abs_hsize,$y1+$f2,$x1+$this->mark_abs_hsize,$y1+$f2);
}
// Stroke a mark with the standard size
// (As long as it is not an image mark )
if( $p[2]->GetType() != MARK_IMG ) {
 
// Clear any user callbacks since we ont want them called for
// the legend marks
$p[2]->iFormatCallback = '';
$p[2]->iFormatCallback2 = '';
 
// Since size for circles is specified as the radius
// this means that we must half the size to make the total
// width behave as the other marks
if( $p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE ) {
$p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)/2);
$p[2]->Stroke($aImg,$x1,$y1+$f2);
}
else {
$p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize));
$p[2]->Stroke($aImg,$x1,$y1+$f2);
}
}
}
elseif ( $p[2] && (is_string($p[3]) || $p[3]>0 ) ) {
// Draw a styled line
$aImg->SetColor($p[1]);
$aImg->SetLineStyle($p[3]);
$aImg->StyleLine($x1-1,$y1+$f2,$x1+$this->mark_abs_hsize,$y1+$f2);
$aImg->StyleLine($x1-1,$y1+$f2+1,$x1+$this->mark_abs_hsize,$y1+$f2+1);
}
else {
// Draw a colored box
$color = $p[1] ;
// We make boxes slightly larger to better show
$boxsize = min($this->mark_abs_vsize,$this->mark_abs_hsize) + 2 ;
$ym = round($y1 + $f2 - $boxsize/2);
// We either need to plot a gradient or a
// pattern. To differentiate we use a kludge.
// Patterns have a p[3] value of < -100
if( $p[3] < -100 ) {
// p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity
if( $patternFactory == null ) {
$patternFactory = new RectPatternFactory();
}
$prect = $patternFactory->Create($p[1][0],$p[1][1],1);
$prect->SetBackground($p[1][3]);
$prect->SetDensity($p[1][2]+1);
$prect->SetPos(new Rectangle($x1,$ym,$boxsize,$boxsize));
$prect->Stroke($aImg);
$prect=null;
}
else {
if( is_array($color) && count($color)==2 ) {
// The client want a gradient color
$grad->FilledRectangle($x1,$ym,
$x1+$boxsize,$ym+$boxsize,
$color[0],$color[1],-$p[3]);
}
else {
$aImg->SetColor($p[1]);
$aImg->FilledRectangle($x1,$ym,$x1+$boxsize,$ym+$boxsize);
}
$aImg->SetColor($this->color);
$aImg->SetLineWeight($fillBoxFrameWeight);
$aImg->Rectangle($x1,$ym,$x1+$boxsize,$ym+$boxsize);
}
}
$aImg->SetColor($this->font_color);
$aImg->SetFont($this->font_family,$this->font_style,$this->font_size);
$aImg->SetTextAlign("left","top");
$aImg->StrokeText(round($x1+$this->mark_abs_hsize+$this->xmargin),$y1,$p[0]);
 
// Add CSIM for Legend if defined
if( $p[4] != "" ) {
$xe = $x1 + $this->xmargin+$this->mark_abs_hsize+$aImg->GetTextWidth($p[0]);
$ye = $y1 + max($this->mark_abs_vsize,$aImg->GetTextHeight($p[0]));
$coords = "$x1,$y1,$xe,$y1,$xe,$ye,$x1,$ye";
if( ! empty($p[4]) ) {
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($p[4])."\"";
 
if( !empty($p[6]) ) {
$this->csimareas .= " target=\"".$p[6]."\"";
}
 
if( !empty($p[5]) ) {
$tmp=sprintf($p[5],$p[0]);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\n";
}
}
if( $i >= $this->layout_n ) {
$x1 = $xp+$this->mark_abs_hsize+$this->xlmargin;
$y1 += $rowheight[$row++];
$i = 1;
}
else {
$x1 += $colwidth[($i-1) % $numcolumns] ;
++$i;
}
}
}
} // Class
 
//===================================================
// CLASS DisplayValue
// Description: Used to print data values at data points
//===================================================
class DisplayValue {
var $show=false,$format="%.1f",$negformat="";
var $iFormCallback='';
var $angle=0;
var $ff=FF_FONT1,$fs=FS_NORMAL,$fsize=10;
var $color="navy",$negcolor="";
var $margin=5,$valign="",$halign="center";
var $iHideZero=false;
 
function Show($aFlag=true) {
$this->show=$aFlag;
}
 
function SetColor($aColor,$aNegcolor="") {
$this->color = $aColor;
$this->negcolor = $aNegcolor;
}
 
function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) {
$this->ff=$aFontFamily;
$this->fs=$aFontStyle;
$this->fsize=$aFontSize;
}
 
function SetMargin($aMargin) {
$this->margin = $aMargin;
}
 
function SetAngle($aAngle) {
$this->angle = $aAngle;
}
 
function SetAlign($aHAlign,$aVAlign='') {
$this->halign = $aHAlign;
$this->valign = $aVAlign;
}
 
function SetFormat($aFormat,$aNegFormat="") {
$this->format= $aFormat;
$this->negformat= $aNegFormat;
}
 
function SetFormatCallback($aFunc) {
$this->iFormCallback = $aFunc;
}
 
function HideZero($aFlag=true) {
$this->iHideZero=$aFlag;
}
 
function Stroke(&$img,$aVal,$x,$y) {
if( $this->show )
{
if( $this->negformat=="" ) $this->negformat=$this->format;
if( $this->negcolor=="" ) $this->negcolor=$this->color;
 
if( $aVal===NULL || (is_string($aVal) && ($aVal=="" || $aVal=="-" || $aVal=="x" ) ) )
return;
 
if( is_numeric($aVal) && $aVal==0 && $this->iHideZero ) {
return;
}
 
// Since the value is used in different cirumstances we need to check what
// kind of formatting we shall use. For example, to display values in a line
// graph we simply display the formatted value, but in the case where the user
// has already specified a text string we don't fo anything.
if( $this->iFormCallback != '' ) {
$f = $this->iFormCallback;
$sval = call_user_func($f,$aVal);
}
elseif( is_numeric($aVal) ) {
if( $aVal >= 0 )
$sval=sprintf($this->format,$aVal);
else
$sval=sprintf($this->negformat,$aVal);
}
else
$sval=$aVal;
 
$y = $y-sign($aVal)*$this->margin;
 
$txt = new Text($sval,$x,$y);
$txt->SetFont($this->ff,$this->fs,$this->fsize);
if( $this->valign == "" ) {
if( $aVal >= 0 )
$valign = "bottom";
else
$valign = "top";
}
else
$valign = $this->valign;
$txt->Align($this->halign,$valign);
 
$txt->SetOrientation($this->angle);
if( $aVal > 0 )
$txt->SetColor($this->color);
else
$txt->SetColor($this->negcolor);
$txt->Stroke($img);
}
}
}
 
//===================================================
// CLASS Plot
// Description: Abstract base class for all concrete plot classes
//===================================================
class Plot {
var $line_weight=1;
var $coords=array();
var $legend='',$hidelegend=false;
var $csimtargets=array(); // Array of targets for CSIM
var $csimwintargets=array(); // Array of window targets for CSIM
var $csimareas=""; // Resultant CSIM area tags
var $csimalts=null; // ALT:s for corresponding target
var $color="black";
var $numpoints=0;
var $weight=1;
var $value;
var $center=false;
var $legendcsimtarget='',$legendcsimwintarget='';
var $legendcsimalt='';
//---------------
// CONSTRUCTOR
function Plot(&$aDatay,$aDatax=false) {
$this->numpoints = count($aDatay);
if( $this->numpoints==0 )
JpGraphError::RaiseL(25121);//("Empty input data array specified for plot. Must have at least one data point.");
$this->coords[0]=$aDatay;
if( is_array($aDatax) ) {
$this->coords[1]=$aDatax;
$n = count($aDatax);
for($i=0; $i < $n; ++$i ) {
if( !is_numeric($aDatax[$i])) {
JpGraphError::RaiseL(25070);
}
}
}
$this->value = new DisplayValue();
}
 
//---------------
// PUBLIC METHODS
 
// Stroke the plot
// "virtual" function which must be implemented by
// the subclasses
function Stroke(&$aImg,&$aXScale,&$aYScale) {
JpGraphError::RaiseL(25122);//("JpGraph: Stroke() must be implemented by concrete subclass to class Plot");
}
 
function HideLegend($f=true) {
$this->hidelegend = $f;
}
 
function DoLegend(&$graph) {
if( !$this->hidelegend )
$this->Legend($graph);
}
 
function StrokeDataValue($img,$aVal,$x,$y) {
$this->value->Stroke($img,$aVal,$x,$y);
}
// Set href targets for CSIM
function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') {
$this->csimtargets=$aTargets;
$this->csimwintargets=$aWinTargets;
$this->csimalts=$aAlts;
}
// Get all created areas
function GetCSIMareas() {
return $this->csimareas;
}
// "Virtual" function which gets called before any scale
// or axis are stroked used to do any plot specific adjustment
function PreStrokeAdjust(&$aGraph) {
if( substr($aGraph->axtype,0,4) == "text" && (isset($this->coords[1])) )
JpGraphError::RaiseL(25123);//("JpGraph: You can't use a text X-scale with specified X-coords. Use a \"int\" or \"lin\" scale instead.");
return true;
}
// Get minimum values in plot
function Min() {
if( isset($this->coords[1]) )
$x=$this->coords[1];
else
$x="";
if( $x != "" && count($x) > 0 ) {
$xm=min($x);
}
else
$xm=0;
$y=$this->coords[0];
$cnt = count($y);
if( $cnt > 0 ) {
/*
if( ! isset($y[0]) ) {
JpGraphError('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)');
}
*/
//$ym = $y[0];
$i=0;
while( $i<$cnt && !is_numeric($ym=$y[$i]) )
$i++;
while( $i < $cnt) {
if( is_numeric($y[$i]) )
$ym=min($ym,$y[$i]);
++$i;
}
}
else
$ym="";
return array($xm,$ym);
}
// Get maximum value in plot
function Max() {
if( isset($this->coords[1]) )
$x=$this->coords[1];
else
$x="";
 
if( $x!="" && count($x) > 0 )
$xm=max($x);
else {
$xm = $this->numpoints-1;
}
$y=$this->coords[0];
if( count($y) > 0 ) {
/*
if( !isset($y[0]) ) {
JpGraphError::Raise('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)');
//$y[0] = 0;
// Change in 1.5.1 Don't treat this as an error any more. Just silently convert to 0
// Change in 1.17 Treat his as an error again !! This is the right way to do !!
}
*/
$cnt = count($y);
$i=0;
while( $i<$cnt && !is_numeric($ym=$y[$i]) )
$i++;
while( $i < $cnt ) {
if( is_numeric($y[$i]) )
$ym=max($ym,$y[$i]);
++$i;
}
}
else
$ym="";
return array($xm,$ym);
}
function SetColor($aColor) {
$this->color=$aColor;
}
function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') {
$this->legend = $aLegend;
$this->legendcsimtarget = $aCSIM;
$this->legendcsimwintarget = $aCSIMWinTarget;
$this->legendcsimalt = $aCSIMAlt;
}
 
function SetWeight($aWeight) {
$this->weight=$aWeight;
}
function SetLineWeight($aWeight=1) {
$this->line_weight=$aWeight;
}
function SetCenter($aCenter=true) {
$this->center = $aCenter;
}
// This method gets called by Graph class to plot anything that should go
// into the margin after the margin color has been set.
function StrokeMargin(&$aImg) {
return true;
}
 
// Framework function the chance for each plot class to set a legend
function Legend(&$aGraph) {
if( $this->legend != "" )
$aGraph->legend->Add($this->legend,$this->color,"",0,$this->legendcsimtarget,
$this->legendcsimalt,$this->legendcsimwintarget);
}
} // Class
 
 
//===================================================
// CLASS PlotLine
// Description:
// Data container class to hold properties for a static
// line that is drawn directly in the plot area.
// Usefull to add static borders inside a plot to show
// for example set-values
//===================================================
class PlotLine {
var $weight=1;
var $color="black";
var $direction=-1;
var $scaleposition;
var $legend='',$hidelegend=false, $legendcsimtarget='', $legendcsimalt='', $legendcsimwintarget='';
var $iLineStyle='solid';
 
 
//---------------
// CONSTRUCTOR
function PlotLine($aDir=HORIZONTAL,$aPos=0,$aColor="black",$aWeight=1) {
$this->direction = $aDir;
$this->color=$aColor;
$this->weight=$aWeight;
$this->scaleposition=$aPos;
}
//---------------
// PUBLIC METHODS
 
function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') {
$this->legend = $aLegend;
$this->legendcsimtarget = $aCSIM;
$this->legendcsimwintarget = $aCSIMWinTarget;
$this->legendcsimalt = $aCSIMAlt;
}
 
function HideLegend($f=true) {
$this->hidelegend = $f;
}
 
function SetPosition($aScalePosition) {
$this->scaleposition=$aScalePosition;
}
function SetDirection($aDir) {
$this->direction = $aDir;
}
function SetColor($aColor) {
$this->color=$aColor;
}
function SetWeight($aWeight) {
$this->weight=$aWeight;
}
 
function SetLineStyle($aStyle) {
$this->iLineStyle = $aStyle;
}
 
//---------------
// PRIVATE METHODS
 
function DoLegend(&$graph) {
if( !$this->hidelegend )
$this->Legend($graph);
}
 
// Framework function the chance for each plot class to set a legend
function Legend(&$aGraph) {
if( $this->legend != "" ) {
$dummyPlotMark = new PlotMark();
$lineStyle = 1;
$aGraph->legend->Add($this->legend,$this->color,$dummyPlotMark,$lineStyle,
$this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
}
}
 
function PreStrokeAdjust($aGraph) {
// Nothing to do
}
function Stroke(&$aImg,&$aXScale,&$aYScale) {
$aImg->SetColor($this->color);
$aImg->SetLineWeight($this->weight);
$oldStyle = $aImg->SetLineStyle($this->iLineStyle);
if( $this->direction == VERTICAL ) {
$ymin_abs=$aYScale->Translate($aYScale->GetMinVal());
$ymax_abs=$aYScale->Translate($aYScale->GetMaxVal());
$xpos_abs=$aXScale->Translate($this->scaleposition);
$aImg->StyleLine($xpos_abs, $ymin_abs, $xpos_abs, $ymax_abs);
}
elseif( $this->direction == HORIZONTAL ) {
$xmin_abs=$aXScale->Translate($aXScale->GetMinVal());
$xmax_abs=$aXScale->Translate($aXScale->GetMaxVal());
$ypos_abs=$aYScale->Translate($this->scaleposition);
$aImg->StyleLine($xmin_abs, $ypos_abs, $xmax_abs, $ypos_abs);
}
else {
JpGraphError::RaiseL(25125);//(" Illegal direction for static line");
}
$aImg->SetLineStyle($oldStyle);
}
}
 
// <EOF>
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpg-config.inc.php
New file
0,0 → 1,216
<?php
//=======================================================================
// File: JPG-CONFIG.INC
// Description: Configuration file for JpGraph library
// Created: 2004-03-27
// Ver: $Id: jpg-config.inc.php 852 2007-03-18 18:18:35Z 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 greek language support
DEFINE("LANGUAGE_GREEK",false);
 
// If you are setting this config to true the conversion of greek characters
// will assume that the input text is windows 1251
DEFINE("GREEK_FROM_WINDOWS",false);
 
// 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);
 
// The following constant is used to auto-detect
// whether cyrillic conversion is really necessary
// if enabled. Just replace 'windows-1251' with a variable
// containing the input character encoding string
// of your application calling jpgraph.
// A typical such string would be 'UTF-8' or 'utf-8'.
// The comparison is case-insensitive.
// If this charset is not a 'koi8-r' or 'windows-1251'
// derivate then no conversion is done.
//
// This constant can be very important in multi-user
// multi-language environments where a cyrillic conversion
// could be needed for some cyrillic people
// and resulting in just erraneous conversions
// for not-cyrillic language based people.
//
// Example: In the free project management
// software dotproject.net $locale_char_set is dynamically
// set by the language environment the user has chosen.
//
// Usage: DEFINE('LANGUAGE_CHARSET', $locale_char_set);
//
// where $locale_char_set is a GLOBAL (string) variable
// from the application including JpGraph.
//
DEFINE('CYRILLIC_LANGUAGE_CHARSET', null);
 
// 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');
 
// Assume that Japanese text have been entered in EUC-JP encoding.
// If this define is true then conversion from EUC-JP to UTF8 is done
// automatically in the library using the mbstring module in PHP.
DEFINE('ASSUME_EUCJP_ENCODING',false);
 
//------------------------------------------------------------------------
// 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 locale for error messages.
// This defaults to English = 'en'
DEFINE('DEFAULT_ERR_LOCALE','en');
 
// 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 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);
 
// 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");
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/lang/de.inc.php
New file
0,0 → 1,498
<?php
/*=======================================================================
// File: DE.INC.PHP
// Description: German language file for error messages
// Created: 2006-03-06
// Author: Timo Leopold (timo@leopold-hh.de)
// Ver: $Id: de.inc.php 982 2008-03-24 11:51:47Z ljp $
//
// Copyright (c)
//========================================================================
*/
 
// Notiz: Das Format fuer jede Fehlermeldung ist array(<Fehlermeldung>,<Anzahl der Argumente>)
$_jpg_messages = array(
 
/*
** Headers wurden bereits gesendet - Fehler. Dies wird als HTML formatiert, weil es direkt als text zurueckgesendet wird
*/
10 => array('<table border="1"><tr><td style="color:darkred;font-size:1.2em;"><b>JpGraph Fehler:</b>
HTTP header wurden bereits gesendet.<br>Fehler in der Datei <b>%s</b> in der Zeile <b>%d</b>.</td></tr><tr><td><b>ErklƤrung:</b><br>HTTP header wurden bereits zum Browser gesendet, wobei die Daten als Text gekennzeichnet wurden, bevor die Bibliothek die Chance hatte, seinen Bild-HTTP-Header zum Browser zu schicken. Dies verhindert, dass die Bibliothek Bilddaten zum Browser schicken kann (weil sie vom Browser als Text interpretiert wĆ¼rden und daher nur Mist dargestellt wĆ¼rde).<p>Wahrscheinlich steht Text im Skript bevor <i>Graph::Stroke()</i> aufgerufen wird. Wenn dieser Text zum Browser gesendet wird, nimmt dieser an, dass die gesamten Daten aus Text bestehen. Such nach irgendwelchem Text, auch nach Leerzeichen und ZeilenumbrĆ¼chen, die eventuell bereits zum Browser gesendet wurden. <p>Zum Beispiel ist ein oft auftretender Fehler, eine Leerzeile am Anfang der Datei oder vor <i>Graph::Stroke()</i> zu lassen."<b>&lt;?php</b>".</td></tr></table>',2),
 
/*
** Setup Fehler
*/
11 => array('Es wurde kein Pfad fĆ¼r CACHE_DIR angegeben. Bitte gib einen Pfad CACHE_DIR in der Datei jpg-config.inc an.',0),
12 => array('Es wurde kein Pfad fĆ¼r TTF_DIR angegeben und der Pfad kann nicht automatisch ermittelt werden. Bitte gib den Pfad in der Datei jpg-config.inc an.',0),
13 => array('The installed PHP version (%s) is not compatible with this release of the library. The library requires at least PHP version %s',2),
 
/*
** jpgraph_bar
*/
 
2001 => array('Die Anzahl der Farben ist nicht gleich der Anzahl der Vorlagen in BarPlot::SetPattern().',0),
2002 => array('Unbekannte Vorlage im Aufruf von BarPlot::SetPattern().',0),
2003 => array('Anzahl der X- und Y-Koordinaten sind nicht identisch. Anzahl der X-Koordinaten: %d; Anzahl der Y-Koordinaten: %d.',2),
2004 => array('Alle Werte fĆ¼r ein Balkendiagramm (barplot) mĆ¼ssen numerisch sein. Du hast den Wert nr [%d] == %s angegeben.',2),
2005 => array('Du hast einen leeren Vektor fĆ¼r die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0),
2006 => array('Unbekannte Position fĆ¼r die Werte der Balken: %s.',1),
2007 => array('Kann GroupBarPlot nicht aus einem leeren Vektor erzeugen.',0),
2008 => array('GroupBarPlot Element nbr %d wurde nicht definiert oder ist leer.',0),
2009 => array('Eins der Objekte, das an GroupBar weitergegeben wurde ist kein Balkendiagramm (BarPlot). Versichere Dich, dass Du den GroupBarPlot aus einem Vektor von Balkendiagrammen (barplot) oder AccBarPlot-Objekten erzeugst. (Class = %s)',1),
2010 => array('Kann AccBarPlot nicht aus einem leeren Vektor erzeugen.',0),
2011 => array('AccBarPlot-Element nbr %d wurde nicht definiert oder ist leer.',1),
2012 => array('Eins der Objekte, das an AccBar weitergegeben wurde ist kein Balkendiagramm (barplot). Versichere Dich, dass Du den AccBar-Plot aus einem Vektor von Balkendiagrammen (barplot) erzeugst. (Class=%s)',1),
2013 => array('Du hast einen leeren Vektor fĆ¼r die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0),
2014 => array('Die Anzahl der Datenpunkte jeder Datenreihe in AccBarPlot muss gleich sein.',0),
 
 
/*
** jpgraph_date
*/
 
3001 => array('Es ist nur mƶglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0),
 
/*
** jpgraph_error
*/
 
4002 => array('Fehler bei den Eingabedaten von LineErrorPlot. Die Anzahl der Datenpunkte mus ein Mehrfaches von drei sein!',0),
 
/*
** jpgraph_flags
*/
 
5001 => array('Unbekannte Flaggen-GrĆ¶ĆŸe (%d).',1),
5002 => array('Der Flaggen-Index %s existiert nicht.',1),
5003 => array('Es wurde eine ungĆ¼ltige Ordnungszahl (%d) fĆ¼r den Flaggen-Index angegeben.',1),
5004 => array('Der Landesname %s hat kein korrespondierendes Flaggenbild. Die Flagge mag existieren, abr eventuell unter einem anderen Namen, z.B. versuche "united states" statt "usa".',1),
 
 
/*
** jpgraph_gantt
*/
 
6001 => array('Interner Fehler. Die Hƶhe fĆ¼r ActivityTitles ist < 0.',0),
6002 => array('Es dĆ¼rfen keine negativen Werte fĆ¼r die Gantt-Diagramm-Dimensionen angegeben werden. Verwende 0, wenn die Dimensionen automatisch ermittelt werden sollen.',0),
6003 => array('UngĆ¼ltiges Format fĆ¼r den Bedingungs-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei index 0 starten und Vektoren in der Form (Row,Constrain-To,Constrain-Type) enthalten.',1),
6004 => array('UngĆ¼ltiges Format fĆ¼r den Fortschritts-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei Index 0 starten und Vektoren in der Form (Row,Progress) enthalten.',1),
6005 => array('SetScale() ist nicht sinnvoll bei Gantt-Diagrammen.',0),
6006 => array('Das Gantt-Diagramm kann nicht automatisch skaliert werden. Es existieren keine AktivitƤten mit Termin. [GetBarMinMax() start >= n]',0),
6007 => array('PlausibiltƤtsprĆ¼fung fĆ¼r die automatische Gantt-Diagramm-GrĆ¶ĆŸe schlug fehl. Entweder die Breite (=%d) oder die Hƶhe (=%d) ist grĆ¶ĆŸer als MAX_GANTTIMG_SIZE. Dies kann mƶglicherweise durch einen falschen Wert bei einer AktivitƤt hervorgerufen worden sein.',2),
6008 => array('Du hast eine Bedingung angegeben von Reihe=%d bis Reihe=%d, die keine AktivitƤt hat.',2),
6009 => array('Unbekannter Bedingungstyp von Reihe=%d bis Reihe=%d',2),
6010 => array('UngĆ¼ltiger Icon-Index fĆ¼r das eingebaute Gantt-Icon [%d]',1),
6011 => array('Argument fĆ¼r IconImage muss entweder ein String oder ein Integer sein.',0),
6012 => array('Unbekannter Typ bei der Gantt-Objekt-Title-Definition.',0),
6015 => array('UngĆ¼ltige vertikale Position %d',1),
6016 => array('Der eingegebene Datums-String (%s) fĆ¼r eine Gantt-AktivitƤt kann nicht interpretiert werden. Versichere Dich, dass es ein gĆ¼ltiger Datumsstring ist, z.B. 2005-04-23 13:30',1),
6017 => array('Unbekannter Datumstyp in GanttScale (%s).',1),
6018 => array('Intervall fĆ¼r Minuten muss ein gerader Teiler einer Stunde sein, z.B. 1,5,10,12,15,20,30, etc. Du hast ein Intervall von %d Minuten angegeben.',1),
6019 => array('Die vorhandene Breite (%d) fĆ¼r die Minuten ist zu klein, um angezeigt zu werden. Bitte benutze die automatische GrĆ¶ĆŸenermittlung oder vergrĆ¶ĆŸere die Breite des Diagramms.',1),
6020 => array('Das Intervall fĆ¼r die Stunden muss ein gerader Teiler eines Tages sein, z.B. 0:30, 1:00, 1:30, 4:00, etc. Du hast ein Intervall von %d eingegeben.',1),
6021 => array('Unbekanntes Format fĆ¼r die Woche.',0),
6022 => array('Die Gantt-Skala wurde nicht eingegeben.',0),
6023 => array('Wenn Du sowohl Stunden als auch Minuten anzeigen lassen willst, muss das Stunden-Interval gleich 1 sein (anderenfalls ist es nicht sinnvoll, Minuten anzeigen zu lassen).',0),
6024 => array('Das CSIM-Ziel muss als String angegeben werden. Der Start des Ziels ist: %d',1),
6025 => array('Der CSIM-Alt-Text muss als String angegeben werden. Der Beginn des Alt-Textes ist: %d',1),
6027 => array('Der Fortschrittswert muss im Bereich [0, 1] liegen.',0),
6028 => array('Die eingegebene Hƶhe (%d) fĆ¼r GanttBar ist nicht im zulƤssigen Bereich.',1),
6029 => array('Der Offset fĆ¼r die vertikale Linie muss im Bereich [0,1] sein.',0),
6030 => array('Unbekannte Pfeilrichtung fĆ¼r eine Verbindung.',0),
6031 => array('Unbekannter Pfeiltyp fĆ¼r eine Verbindung.',0),
6032 => array('Interner Fehler: Unbekannter Pfadtyp (=%d) fĆ¼r eine Verbindung.',1),
 
/*
** jpgraph_gradient
*/
 
7001 => array('Unbekannter Gradiententyp (=%d).',1),
 
/*
** jpgraph_iconplot
*/
 
8001 => array('Der Mix-Wert fĆ¼r das Icon muss zwischen 0 und 100 sein.',0),
8002 => array('Die Ankerposition fĆ¼r Icons muss entweder "top", "bottom", "left", "right" oder "center" sein.',0),
8003 => array('Es ist nicht mƶglich, gleichzeitig ein Bild und eine Landesflagge fĆ¼r dasselbe Icon zu definieren',0),
8004 => array('Wenn Du Landesflaggen benutzen willst, musst Du die Datei "jpgraph_flags.php" hinzufĆ¼gen (per include).',0),
 
/*
** jpgraph_imgtrans
*/
 
9001 => array('Der Wert fĆ¼r die Bildtransformation ist auƟerhalb des zulƤssigen Bereichs. Der verschwindende Punkt am Horizont muss als Wert zwischen 0 und 1 angegeben werden.',0),
 
/*
** jpgraph_lineplot
*/
 
10001 => array('Die Methode LinePlot::SetFilled() sollte nicht mehr benutzt werden. Benutze lieber SetFillColor()',0),
10002 => array('Der Plot ist zu kompliziert fĆ¼r FastLineStroke. Benutze lieber den StandardStroke()',0),
10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0),
/*
** jpgraph_log
*/
 
11001 => array('Deine Daten enthalten nicht-numerische Werte.',0),
11002 => array('Negative Werte kƶnnen nicht fĆ¼r logarithmische Achsen verwendet werden.',0),
11003 => array('Deine Daten enthalten nicht-numerische Werte.',0),
11004 => array('Skalierungsfehler fĆ¼r die logarithmische Achse. Es gibt ein Problem mit den Daten der Achse. Der grĆ¶ĆŸte Wert muss grĆ¶ĆŸer sein als Null. Es ist mathematisch nicht mƶglich, einen Wert gleich Null in der Skala zu haben.',0),
11005 => array('Das Tick-Intervall fĆ¼r die logarithmische Achse ist nicht definiert. Lƶsche jeden Aufruf von SetTextLabelStart() oder SetTextTickInterval() bei der logarithmischen Achse.',0),
 
/*
** jpgraph_mgraph
*/
 
12001 => array("Du benutzt GD 2.x und versuchst ein Nicht-Truecolor-Bild als Hintergrundbild zu benutzen. Um Hintergrundbilder mit GD 2.x zu benutzen, ist es notwendig Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die QualitƤt der Truetype-Schriften sehr schlecht, wenn man Truetype-Schriften mit Truecolor-Bildern verwendet.",0),
12002 => array('UngĆ¼ltiger Dateiname fĆ¼r MGraph::SetBackgroundImage() : %s. Die Datei muss eine gĆ¼ltige Dateierweiterung haben (jpg,gif,png), wenn die automatische Typerkennung verwendet wird.',1),
12003 => array('Unbekannte Dateierweiterung (%s) in MGraph::SetBackgroundImage() fĆ¼r Dateiname: %s',2),
12004 => array('Das Bildformat des Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstĆ¼tzt. ',1),
12005 => array('Das Hintergrundbild kann nicht gelesen werden: %s',1),
12006 => array('Es wurden ungĆ¼ltige GrĆ¶ĆŸen fĆ¼r Breite oder Hƶhe beim Erstellen des Bildes angegeben, (Breite=%d, Hƶhe=%d)',2),
12007 => array('Das Argument fĆ¼r MGraph::Add() ist nicht gĆ¼ltig fĆ¼r GD.',0),
12008 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Bildformate zu unterstĆ¼tzen.',0),
12009 => array('Deine PHP-Installation unterstĆ¼tzt das gewƤhlte Bildformat nicht: %s',1),
12010 => array('Es konnte kein Bild als Datei %s erzeugt werden. ƜberprĆ¼fe, ob Du die entsprechenden Schreibrechte im aktuellen Verzeichnis hast.',1),
12011 => array('Es konnte kein Truecolor-Bild erzeugt werden. ƜberprĆ¼fe, ob Du wirklich die GD2-Bibliothek installiert hast.',0),
12012 => array('Es konnte kein Bild erzeugt werden. ƜberprĆ¼fe, ob Du wirklich die GD2-Bibliothek installiert hast.',0),
 
/*
** jpgraph_pie3d
*/
 
14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der TortenstĆ¼cke zu kontrollieren.',0),
14002 => array('PiePlot3D::SetAngle() 3D-Torten-Projektionswinkel muss zwischen 5 und 85 Grad sein.',0),
14003 => array('Interne Festlegung schlug fehl. Pie3D::Pie3DSlice',0),
14004 => array('TortenstĆ¼ck-Startwinkel muss zwischen 0 und 360 Grad sein.',0),
14005 => array('Pie3D Interner Fehler: Versuch, zweimal zu umhĆ¼llen bei der Suche nach dem Startindex.',0,),
14006 => array('Pie3D Interner Fehler: Z-Sortier-Algorithmus fĆ¼r 3D-Tortendiagramme funktioniert nicht einwandfrei (2). Versuch, zweimal zu umhĆ¼llen beim Erstellen des Bildes.',0),
14007 => array('Die Breite fĆ¼r das 3D-Tortendiagramm ist 0. Gib eine Breite > 0 an.',0),
 
/*
** jpgraph_pie
*/
 
15001 => array('PiePLot::SetTheme() Unbekannter Stil: %s',1),
15002 => array('Argument fĆ¼r PiePlot::ExplodeSlice() muss ein Integer-Wert sein',0),
15003 => array('Argument fĆ¼r PiePlot::Explode() muss ein Vektor mit Integer-Werten sein.',0),
15004 => array('TortenstĆ¼ck-Startwinkel muss zwischen 0 und 360 Grad sein.',0),
15005 => array('PiePlot::SetFont() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetFont().',0),
15006 => array('PiePlot::SetSize() Radius fĆ¼r Tortendiagramm muss entweder als Bruch [0, 0.5] der BildgrĆ¶ĆŸe oder als Absoluwert in Pixel im Bereich [10, 1000] angegeben werden.',0),
15007 => array('PiePlot::SetFontColor() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetColor()..',0),
15008 => array('PiePlot::SetLabelType() der Typ fĆ¼r Tortendiagramme muss entweder 0 or 1 sein (nicht %d).',1),
15009 => array('UngĆ¼ltiges Tortendiagramm. Die Summe aller Daten ist Null.',0),
15010 => array('Die Summe aller Daten ist Null.',0),
15011 => array('Um Bildtransformationen benutzen zu kƶnnen, muss die Datei jpgraph_imgtrans.php eingefĆ¼gt werden (per include).',0),
 
/*
** jpgraph_plotband
*/
 
16001 => array('Die Dichte fĆ¼r das Pattern muss zwischen 1 und 100 sein. (Du hast %f eingegeben)',1),
16002 => array('Es wurde keine Position fĆ¼r das Pattern angegeben.',0),
16003 => array('Unbekannte Pattern-Definition (%d)',0),
16004 => array('Der Mindeswert fĆ¼r das PlotBand ist grĆ¶ĆŸer als der Maximalwert. Bitte korrigiere dies!',0),
 
 
/*
** jpgraph_polar
*/
 
17001 => array('PolarPlots mĆ¼ssen eine gerade Anzahl von Datenpunkten haben. Jeder Datenpunkt ist ein Tupel (Winkel, Radius).',0),
17002 => array('Unbekannte Ausrichtung fĆ¼r X-Achsen-Titel. (%s)',1),
//17003 => array('Set90AndMargin() wird fĆ¼r PolarGraph nicht unterstĆ¼tzt.',0),
17004 => array('Unbekannter Achsentyp fĆ¼r PolarGraph. Er muss entweder \'lin\' oder \'log\' sein.',0),
 
/*
** jpgraph_radar
*/
 
18001 => array('ClientSideImageMaps werden fĆ¼r RadarPlots nicht unterstĆ¼tzt.',0),
18002 => array('RadarGraph::SupressTickMarks() sollte nicht mehr verwendet werden. Benutze stattdessen HideTickMarks().',0),
18003 => array('UngĆ¼ltiger Achsentyp fĆ¼r RadarPlot (%s). Er muss entweder \'lin\' oder \'log\' sein.',1),
18004 => array('Die RadarPlot-GrĆ¶ĆŸe muss zwischen 0.1 und 1 sein. (Dein Wert=%f)',1),
18005 => array('RadarPlot: nicht unterstĆ¼tzte Tick-Dichte: %d',1),
18006 => array('Minimum Daten %f (RadarPlots sollten nur verwendet werden, wenn alle Datenpunkte einen Wert > 0 haben).',1),
18007 => array('Die Anzahl der Titel entspricht nicht der Anzahl der Datenpunkte.',0),
18008 => array('Jeder RadarPlot muss die gleiche Anzahl von Datenpunkten haben.',0),
 
/*
** jpgraph_regstat
*/
 
19001 => array('Spline: Anzahl der X- und Y-Koordinaten muss gleich sein.',0),
19002 => array('UngĆ¼ltige Dateneingabe fĆ¼r Spline. Zwei oder mehr aufeinanderfolgende X-Werte sind identisch. Jeder eigegebene X-Wert muss unterschiedlich sein, weil vom mathematischen Standpunkt ein Eins-zu-Eins-Mapping vorliegen muss, d.h. jeder X-Wert korrespondiert mit exakt einem Y-Wert.',0),
19003 => array('Bezier: Anzahl der X- und Y-Koordinaten muss gleich sein.',0),
 
/*
** jpgraph_scatter
*/
 
20001 => array('Fieldplots mĆ¼ssen die gleiche Anzahl von X und Y Datenpunkten haben.',0),
20002 => array('Bei Fieldplots muss ein Winkel fĆ¼r jeden X und Y Datenpunkt angegeben werden.',0),
20003 => array('Scatterplots mĆ¼ssen die gleiche Anzahl von X- und Y-Datenpunkten haben.',0),
 
/*
** jpgraph_stock
*/
 
21001 => array('Die Anzahl der Datenwerte fĆ¼r Stock-Charts mĆ¼ssen ein Mehrfaches von %d Datenpunkten sein.',1),
 
/*
** jpgraph_plotmark
*/
 
23001 => array('Der Marker "%s" existiert nicht in der Farbe: %d',2),
23002 => array('Der Farb-Index ist zu hoch fĆ¼r den Marker "%s"',1),
23003 => array('Ein Dateiname muss angegeben werden, wenn Du den Marker-Typ auf MARK_IMG setzt.',0),
 
/*
** jpgraph_utils
*/
 
24001 => array('FuncGenerator : Keine Funktion definiert. ',0),
24002 => array('FuncGenerator : Syntax-Fehler in der Funktionsdefinition ',0),
24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0),
 
/*
** jpgraph
*/
 
25001 => array('Diese PHP-Installation ist nicht mit der GD-Bibliothek kompiliert. Bitte kompiliere PHP mit GD-UnterstĆ¼tzung neu, damit JpGraph funktioniert. (Weder die Funktion imagetypes() noch imagecreatefromstring() existiert!)',0),
25002 => array('Diese PHP-Installation scheint nicht die benƶtigte GD-Bibliothek zu unterstĆ¼tzen. Bitte schau in der PHP-Dokumentation nach, wie man die GD-Bibliothek installiert und aktiviert.',0),
25003 => array('Genereller PHP Fehler : Bei %s:%d : %s',3),
25004 => array('Genereller PHP Fehler : %s ',1),
25005 => array('PHP_SELF, die PHP-Global-Variable kann nicht ermittelt werden. PHP kann nicht von der Kommandozeile gestartet werden, wenn der Cache oder die Bilddateien automatisch benannt werden sollen.',0),
25006 => array('Die Benutzung der FF_CHINESE (FF_BIG5) Schriftfamilie benƶtigt die iconv() Funktion in Deiner PHP-Konfiguration. Dies wird nicht defaultmƤƟig in PHP kompiliert (benƶtigt "--width-iconv" bei der Konfiguration).',0),
25007 => array('Du versuchst das lokale (%s) zu verwenden, was von Deiner PHP-Installation nicht unterstĆ¼tzt wird. Hinweis: Benutze \'\', um das defaultmƤƟige Lokale fĆ¼r diese geographische Region festzulegen.',1),
25008 => array('Die Bild-Breite und Hƶhe in Graph::Graph() mĆ¼ssen numerisch sein',0),
25009 => array('Die Skalierung der Achsen muss angegeben werden mit Graph::SetScale()',0),
 
25010 => array('Graph::Add() Du hast versucht, einen leeren Plot zum Graph hinzuzufĆ¼gen.',0),
25011 => array('Graph::AddY2() Du hast versucht, einen leeren Plot zum Graph hinzuzufĆ¼gen.',0),
25012 => array('Graph::AddYN() Du hast versucht, einen leeren Plot zum Graph hinzuzufĆ¼gen.',0),
25013 => array('Es kƶnnen nur Standard-Plots zu multiplen Y-Achsen hinzugefĆ¼gt werden',0),
25014 => array('Graph::AddText() Du hast versucht, einen leeren Text zum Graph hinzuzufĆ¼gen.',0),
25015 => array('Graph::AddLine() Du hast versucht, eine leere Linie zum Graph hinzuzufĆ¼gen.',0),
25016 => array('Graph::AddBand() Du hast versucht, ein leeres Band zum Graph hinzuzufĆ¼gen.',0),
25017 => array('Du benutzt GD 2.x und versuchst, ein Hintergrundbild in einem Truecolor-Bild zu verwenden. Um Hintergrundbilder mit GD 2.x zu verwenden, ist es notwendig, Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die QualitƤt der Schrift sehr schlecht, wenn Truetype-Schrift in Truecolor-Bildern verwendet werden.',0),
25018 => array('Falscher Dateiname fĆ¼r Graph::SetBackgroundImage() : "%s" muss eine gĆ¼ltige Dateinamenerweiterung (jpg,gif,png) haben, wenn die automatische Dateityperkennung verwenndet werden soll.',1),
25019 => array('Unbekannte Dateinamenerweiterung (%s) in Graph::SetBackgroundImage() fĆ¼r Dateiname: "%s"',2),
 
25020 => array('Graph::SetScale(): Dar Maximalwert muss grĆ¶ĆŸer sein als der Mindestwert.',0),
25021 => array('Unbekannte Achsendefinition fĆ¼r die Y-Achse. (%s)',1),
25022 => array('Unbekannte Achsendefinition fĆ¼r die X-Achse. (%s)',1),
25023 => array('Nicht unterstĆ¼tzter Y2-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1),
25024 => array('Nicht unterstĆ¼tzter X-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1),
25025 => array('Nicht unterstĆ¼tzte Tick-Dichte: %d',1),
25026 => array('Nicht unterstĆ¼tzter Typ der nicht angegebenen Y-Achse. Du hast entweder: 1. einen Y-Achsentyp fĆ¼r automatisches Skalieren definiert, aber keine Plots angegeben. 2. eine Achse direkt definiert, aber vergessen, die Tick-Dichte zu festzulegen.',0),
25027 => array('Kann cached CSIM "%s" zum Lesen nicht ƶffnen.',1),
25028 => array('Apache/PHP hat keine Schreibrechte, in das CSIM-Cache-Verzeichnis (%s) zu schreiben. ƜberprĆ¼fe die Rechte.',1),
25029 => array('Kann nicht in das CSIM "%s" schreiben. ƜberprĆ¼fe die Schreibrechte und den freien Speicherplatz.',1),
 
25030 => array('Fehlender Skriptname fĆ¼r StrokeCSIM(). Der Name des aktuellen Skriptes muss als erster Parameter von StrokeCSIM() angegeben werden.',0),
25031 => array('Der Achsentyp muss mittels Graph::SetScale() angegeben werden.',0),
25032 => array('Es existieren keine Plots fĆ¼r die Y-Achse nbr:%d',1),
25033 => array('',0),
25034 => array('Undefinierte X-Achse kann nicht gezeichnet werden. Es wurden keine Plots definiert.',0),
25035 => array('Du hast Clipping aktiviert. Clipping wird nur fĆ¼r Diagramme mit 0 oder 90 Grad Rotation unterstĆ¼tzt. Bitte verƤndere Deinen Rotationswinkel (=%d Grad) dementsprechend oder deaktiviere Clipping.',1),
25036 => array('Unbekannter Achsentyp AxisStyle() : %s',1),
25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstĆ¼tzt. ',1),
25038 => array('Das Hintergrundbild scheint von einem anderen Typ (unterschiedliche Dateierweiterung) zu sein als der angegebene Typ. Angegebenen: %s; Datei: %s',2),
25039 => array('Hintergrundbild kann nicht gelesen werden: "%s"',1),
 
25040 => array('Es ist nicht mƶglich, sowohl ein Hintergrundbild als auch eine Hintergrund-Landesflagge anzugeben.',0),
25041 => array('Um Landesflaggen als Hintergrund benutzen zu kƶnnen, muss die Datei "jpgraph_flags.php" eingefĆ¼gt werden (per include).',0),
25042 => array('Unbekanntes Hintergrundbild-Layout',0),
25043 => array('Unbekannter Titelhintergrund-Stil.',0),
25044 => array('Automatisches Skalieren kann nicht verwendet werden, weil es unmƶglich ist, einen gĆ¼ltigen min/max Wert fĆ¼r die Y-Achse zu ermitteln (nur Null-Werte).',0),
25045 => array('Die Schriftfamilien FF_HANDWRT und FF_BOOK sind wegen Copyright-Problemen nicht mehr verfĆ¼gbar. Diese Schriften kƶnnen nicht mehr mit JpGraph verteilt werden. Bitte lade Dir Schriften von http://corefonts.sourceforge.net/ herunter.',0),
25046 => array('Angegebene TTF-Schriftfamilie (id=%d) ist unbekannt oder existiert nicht. Bitte merke Dir, dass TTF-Schriften wegen Copyright-Problemen nicht mit JpGraph mitgeliefert werden. Du findest MS-TTF-Internetschriften (arial, courier, etc.) zum Herunterladen unter http://corefonts.sourceforge.net/',1),
25047 => array('Stil %s ist nicht verfĆ¼gbar fĆ¼r Schriftfamilie %s',2),
25048 => array('Unbekannte Schriftstildefinition [%s].',1),
25049 => array('Schriftdatei "%s" ist nicht lesbar oder existiert nicht.',1),
 
25050 => array('Erstes Argument fĆ¼r Text::Text() muss ein String sein.',0),
25051 => array('UngĆ¼ltige Richtung angegeben fĆ¼r Text.',0),
25052 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte vertikale Ausrichtung fĆ¼r Text.',0),
25053 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte horizontale Ausrichtung fĆ¼r Text.',0),
25054 => array('Interner Fehler: Unbekannte Grid-Achse %s',1),
25055 => array('Axis::SetTickDirection() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetTickSide().',0),
25056 => array('SetTickLabelMargin() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelMargin().',0),
25057 => array('SetTextTicks() sollte nicht mehr verwendet werden. Benutze stattdessen SetTextTickInterval().',0),
25058 => array('TextLabelIntevall >= 1 muss angegeben werden.',0),
25059 => array('SetLabelPos() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelSide().',0),
 
25060 => array('Unbekannte Ausrichtung angegeben fĆ¼r X-Achsentitel (%s).',1),
25061 => array('Unbekannte Ausrichtung angegeben fĆ¼r Y-Achsentitel (%s).',1),
25062 => array('Label unter einem Winkel werden fĆ¼r die Y-Achse nicht unterstĆ¼tzt.',0),
25063 => array('Ticks::SetPrecision() sollte nicht mehr verwendet werden. Benutze stattdessen Ticks::SetLabelFormat() (oder Ticks::SetFormatCallback()).',0),
25064 => array('Kleinere oder grĆ¶ĆŸere SchrittgrĆ¶ĆŸe ist 0. ƜberprĆ¼fe, ob Du fƤlschlicherweise SetTextTicks(0) in Deinem Skript hast. Wenn dies nicht der Fall ist, bist Du eventuell Ć¼ber einen Bug in JpGraph gestolpert. Bitte sende einen Report und fĆ¼ge den Code an, der den Fehler verursacht hat.',0),
25065 => array('Tick-Positionen mĆ¼ssen als array() angegeben werden',0),
25066 => array('Wenn die Tick-Positionen und -Label von Hand eingegeben werden, muss die Anzahl der Ticks und der Label gleich sein.',0),
25067 => array('Deine von Hand eingegebene Achse und Ticks sind nicht korrekt. Die Skala scheint zu klein zu sein fĆ¼r den Tickabstand.',0),
25068 => array('Ein Plot hat eine ungĆ¼ltige Achse. Dies kann beispielsweise der Fall sein, wenn Du automatisches Text-Skalieren verwendest, um ein Liniendiagramm zu zeichnen mit nur einem Datenpunkt, oder wenn die BildflƤche zu klein ist. Es kann auch der Fall sein, dass kein Datenpunkt einen numerischen Wert hat (vielleicht nur \'-\' oder \'x\').',0),
25069 => array('Grace muss grĆ¶ĆŸer sein als 0',0),
 
25070 => array('Deine Daten enthalten nicht-numerische Werte.',0),
25071 => array('Du hast mit SetAutoMin() einen Mindestwert angegeben, der grĆ¶ĆŸer ist als der Maximalwert fĆ¼r die Achse. Dies ist nicht mƶglich.',0),
25072 => array('Du hast mit SetAutoMax() einen Maximalwert angegeben, der kleiner ist als der Minimalwert der Achse. Dies ist nicht mƶglich.',0),
25073 => array('Interner Fehler. Der Integer-Skalierungs-Algorithmus-Vergleich ist auƟerhalb der Grenzen (r=%f).',1),
25074 => array('Interner Fehler. Der Skalierungsbereich ist negativ (%f) [fĆ¼r %s Achse]. Dieses Problem kƶnnte verursacht werden durch den Versuch, \'ungĆ¼ltige\' Werte in die Daten-Vektoren einzugeben (z.B. nur String- oder NULL-Werte), was beim automatischen Skalieren einen Fehler erzeugt.',2),
25075 => array('Die automatischen Ticks kƶnnen nicht gesetzt werden, weil min==max.',0),
25077 => array('Einstellfaktor fĆ¼r die Farbe muss grĆ¶ĆŸer sein als 0',0),
25078 => array('Unbekannte Farbe: %s',1),
25079 => array('Unbekannte Farbdefinition: %s, GrĆ¶ĆŸe=%d',2),
 
25080 => array('Der Alpha-Parameter fĆ¼r Farben muss zwischen 0.0 und 1.0 liegen.',0),
25081 => array('Das ausgewƤhlte Grafikformat wird entweder nicht unterstĆ¼tzt oder ist unbekannt [%s]',1),
25082 => array('Es wurden ungĆ¼ltige GrĆ¶ĆŸen fĆ¼r Breite und Hƶhe beim Erstellen des Bildes definiert (Breite=%d, Hƶhe=%d).',2),
25083 => array('Es wurde eine ungĆ¼ltige GrĆ¶ĆŸe beim Kopieren des Bildes angegeben. Die GrĆ¶ĆŸe fĆ¼r das kopierte Bild wurde auf 1 Pixel oder weniger gesetzt.',0),
25084 => array('Fehler beim Erstellen eines temporƤren GD-Canvas. Mƶglicherweise liegt ein Arbeitsspeicherproblem vor.',0),
25085 => array('Ein Bild kann nicht aus dem angegebenen String erzeugt werden. Er ist entweder in einem nicht unterstĆ¼tzen Format oder er represƤntiert ein kaputtes Bild.',0),
25086 => array('Du scheinst nur GD 1.x installiert zu haben. Um Alphablending zu aktivieren, ist GD 2.x oder hƶher notwendig. Bitte installiere GD 2.x oder versichere Dich, dass die Konstante USE_GD2 richtig gesetzt ist. StandardmƤƟig wird die installierte GD-Version automatisch erkannt. Ganz selten wird GD2 erkannt, obwohl nur GD1 installiert ist. Die Konstante USE_GD2 muss dann zu "false" gesetzt werden.',0),
25087 => array('Diese PHP-Version wurde ohne TTF-UnterstĆ¼tzung konfiguriert. PHP muss mit TTF-UnterstĆ¼tzung neu kompiliert und installiert werden.',0),
25088 => array('Die GD-SchriftunterstĆ¼tzung wurde falsch konfiguriert. Der Aufruf von imagefontwidth() ist fehlerhaft.',0),
25089 => array('Die GD-SchriftunterstĆ¼tzung wurde falsch konfiguriert. Der Aufruf von imagefontheight() ist fehlerhaft.',0),
 
25090 => array('Unbekannte Richtung angegeben im Aufruf von StrokeBoxedText() [%s].',1),
25091 => array('Die interne Schrift untestĆ¼tzt das Schreiben von Text in einem beliebigen Winkel nicht. Benutze stattdessen TTF-Schriften.',0),
25092 => array('Es liegt entweder ein Konfigurationsproblem mit TrueType oder ein Problem beim Lesen der Schriftdatei "%s" vor. Versichere Dich, dass die Datei existiert und Leserechte und -pfad vergeben sind. (wenn \'basedir\' restriction in PHP aktiviert ist, muss die Schriftdatei im Dokumentwurzelverzeichnis abgelegt werden). Mƶglicherweise ist die FreeType-Bibliothek falsch installiert. Versuche, mindestens zur FreeType-Version 2.1.13 zu aktualisieren und kompiliere GD mit einem korrekten Setup neu, damit die FreeType-Bibliothek gefunden werden kann.',1),
25093 => array('Die Schriftdatei "%s" kann nicht gelesen werden beim Aufruf von Image::GetBBoxTTF. Bitte versichere Dich, dass die Schrift gesetzt wurde, bevor diese Methode aufgerufen wird, und dass die Schrift im TTF-Verzeichnis installiert ist.',1),
25094 => array('Die Textrichtung muss in einem Winkel zwischen 0 und 90 engegeben werden.',0),
25095 => array('Unbekannte Schriftfamilien-Definition. ',0),
25096 => array('Der Farbpalette kƶnnen keine weiteren Farben zugewiesen werden. Dem Bild wurde bereits die grĆ¶ĆŸtmƶgliche Anzahl von Farben (%d) zugewiesen und die Palette ist voll. Verwende stattdessen ein TrueColor-Bild',0),
25097 => array('Eine Farbe wurde als leerer String im Aufruf von PushColor() angegegeben.',0),
25098 => array('Negativer Farbindex. Unpassender Aufruf von PopColor().',0),
25099 => array('Die Parameter fĆ¼r Helligkeit und Kontrast sind auƟerhalb des zulƤssigen Bereichs [-1,1]',0),
 
25100 => array('Es liegt ein Problem mit der Farbpalette und dem GD-Setup vor. Bitte deaktiviere anti-aliasing oder verwende GD2 mit TrueColor. Wenn die GD2-Bibliothek installiert ist, versichere Dich, dass die Konstante USE_GD2 auf "true" gesetzt und TrueColor aktiviert ist.',0),
25101 => array('UngĆ¼ltiges numerisches Argument fĆ¼r SetLineStyle(): (%d)',1),
25102 => array('UngĆ¼ltiges String-Argument fĆ¼r SetLineStyle(): %s',1),
25103 => array('UngĆ¼ltiges Argument fĆ¼r SetLineStyle %s',1),
25104 => array('Unbekannter Linientyp: %s',1),
25105 => array('Es wurden NULL-Daten fĆ¼r ein gefĆ¼lltes Polygon angegeben. Sorge dafĆ¼r, dass keine NULL-Daten angegeben werden.',0),
25106 => array('Image::FillToBorder : es kƶnnen keine weiteren Farben zugewiesen werden.',0),
25107 => array('In Datei "%s" kann nicht geschrieben werden. ƜberprĆ¼fe die aktuellen Schreibrechte.',1),
25108 => array('Das Bild kann nicht gestreamt werden. Mƶglicherweise liegt ein Fehler im PHP/GD-Setup vor. Kompiliere PHP neu und verwende die eingebaute GD-Bibliothek, die mit PHP angeboten wird.',0),
25109 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Grafikformate zu unterstĆ¼tzen. Sorge zunƤchst dafĆ¼r, dass GD als PHP-Modul kompiliert ist. Wenn Du auƟerdem JPEG-Bilder verwenden willst, musst Du die JPEG-Bibliothek installieren. Weitere Details sind in der PHP-Dokumentation zu finden.',0),
 
25110 => array('Dein PHP-Installation unterstĆ¼tzt das gewƤhlte Grafikformat nicht: %s',1),
25111 => array('Das gecachete Bild %s kann nicht gelƶscht werden. Problem mit den Rechten?',1),
25112 => array('Das Datum der gecacheten Datei (%s) liegt in der Zukunft.',1),
25113 => array('Das gecachete Bild %s kann nicht gelƶscht werden. Problem mit den Rechten?',1),
25114 => array('PHP hat nicht die erforderlichen Rechte, um in die Cache-Datei %s zu schreiben. Bitte versichere Dich, dass der Benutzer, der PHP anwendet, die entsprechenden Schreibrechte fĆ¼r die Datei hat, wenn Du das Cache-System in JPGraph verwenden willst.',1),
25115 => array('Berechtigung fĆ¼r gecachetes Bild %s kann nicht gesetzt werden. Problem mit den Rechten?',1),
25116 => array('Datei kann nicht aus dem Cache %s geƶffnet werden',1),
25117 => array('Gecachetes Bild %s kann nicht zum Lesen geƶffnet werden.',1),
25118 => array('Verzeichnis %s kann nicht angelegt werden. Versichere Dich, dass PHP die Schreibrechte in diesem Verzeichnis hat.',1),
25119 => array('Rechte fĆ¼r Datei %s kƶnnen nicht gesetzt werden. Problem mit den Rechten?',1),
 
25120 => array('Die Position fĆ¼r die Legende muss als Prozentwert im Bereich 0-1 angegeben werden.',0),
25121 => array('Eine leerer Datenvektor wurde fĆ¼r den Plot eingegeben. Es muss wenigstens ein Datenpunkt vorliegen.',0),
25122 => array('Stroke() muss als Subklasse der Klasse Plot definiert sein.',0),
25123 => array('Du kannst keine Text-X-Achse mit X-Koordinaten verwenden. Benutze stattdessen eine "int" oder "lin" Achse.',0),
25124 => array('Der Eingabedatenvektor mus aufeinanderfolgende Werte von 0 aufwƤrts beinhalten. Der angegebene Y-Vektor beginnt mit leeren Werten (NULL).',0),
25125 => array('UngĆ¼ltige Richtung fĆ¼r statische Linie.',0),
25126 => array('Es kann kein TrueColor-Bild erzeugt werden. ƜberprĆ¼fe, ob die GD2-Bibliothek und PHP korrekt aufgesetzt wurden.',0),
25127 => array('The library has been configured for automatic encoding conversion of Japanese fonts. This requires that PHP has the mb_convert_encoding() function. Your PHP installation lacks this function (PHP needs the "--enable-mbstring" when compiled).',0),
 
/*
**---------------------------------------------------------------------------------------------
** Pro-version strings
**---------------------------------------------------------------------------------------------
*/
 
/*
** jpgraph_table
*/
 
27001 => array('GTextTable: UngĆ¼ltiges Argument fĆ¼r Set(). Das Array-Argument muss 2-- dimensional sein.',0),
27002 => array('GTextTable: UngĆ¼ltiges Argument fĆ¼r Set()',0),
27003 => array('GTextTable: Falsche Anzahl von Argumenten fĆ¼r GTextTable::SetColor()',0),
27004 => array('GTextTable: Angegebener Zellenbereich, der verschmolzen werden soll, ist ungĆ¼ltig.',0),
27005 => array('GTextTable: Bereits verschmolzene Zellen im Bereich (%d,%d) bis (%d,%d) kƶnnen nicht ein weiteres Mal verschmolzen werden.',4),
27006 => array('GTextTable: Spalten-Argument = %d liegt auƟerhalb der festgelegten TabellengrĆ¶ĆŸe.',1),
27007 => array('GTextTable: Zeilen-Argument = %d liegt auƟerhalb der festgelegten TabellengrĆ¶ĆŸe.',1),
27008 => array('GTextTable: Spalten- und ZeilengrĆ¶ĆŸe mĆ¼ssen zu den Dimensionen der Tabelle passen.',0),
27009 => array('GTextTable: Die Anzahl der Tabellenspalten oder -zeilen ist 0. Versichere Dich, dass die Methoden Init() oder Set() aufgerufen werden.',0),
27010 => array('GTextTable: Es wurde keine Ausrichtung beim Aufruf von SetAlign() angegeben.',0),
27011 => array('GTextTable: Es wurde eine unbekannte Ausrichtung beim Aufruf von SetAlign() abgegeben. Horizontal=%s, Vertikal=%s',2),
27012 => array('GTextTable: Interner Fehler. Es wurde ein ungĆ¼ltiges Argument festgeleget %s',1),
27013 => array('GTextTable: Das Argument fĆ¼r FormatNumber() muss ein String sein.',0),
27014 => array('GTextTable: Die Tabelle wurde weder mit einem Aufruf von Set() noch von Init() initialisiert.',0),
27015 => array('GTextTable: Der Zellenbildbedingungstyp muss entweder TIMG_WIDTH oder TIMG_HEIGHT sein.',0),
 
/*
** jpgraph_windrose
*/
 
22001 => array('Die Gesamtsumme der prozentualen Anteile aller Windrosenarme darf 100%% nicht Ć¼berschreiten!\n(Aktuell max: %d)',1),
22002 => array('Das Bild ist zu klein fĆ¼r eine Skala. Bitte vergrĆ¶ĆŸere das Bild.',0),
22004 => array('Die Etikettendefinition fĆ¼r Windrosenrichtungen mĆ¼ssen 16 Werte haben (eine fĆ¼r jede Kompassrichtung).',0),
22005 => array('Der Linientyp fĆ¼r radiale Linien muss einer von ("solid","dotted","dashed","longdashed") sein.',0),
22006 => array('Es wurde ein ungĆ¼ltiger Windrosentyp angegeben.',0),
22007 => array('Es wurden zu wenig Werte fĆ¼r die Bereichslegende angegeben.',0),
22008 => array('Interner Fehler: Versuch, eine freie Windrose zu plotten, obwohl der Typ keine freie Windrose ist.',0),
22009 => array('Du hast die gleiche Richtung zweimal angegeben, einmal mit einem Winkel und einmal mit einer Kompassrichtung (%f Grad).',0),
22010 => array('Die Richtung muss entweder ein numerischer Wert sein oder eine der 16 Kompassrichtungen',0),
22011 => array('Der Windrosenindex muss ein numerischer oder Richtungswert sein. Du hast angegeben Index=%d',1),
22012 => array('Die radiale Achsendefinition fĆ¼r die Windrose enthƤlt eine nicht aktivierte Richtung.',0),
22013 => array('Du hast dasselbe Look&Feel fĆ¼r die gleiche Kompassrichtung zweimal engegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1),
22014 => array('Der Index fĆ¼r eine Kompassrichtung muss zwischen 0 und 15 sein.',0),
22015 => array('Du hast einen unbekannten Windrosenplottyp angegeben.',0),
22016 => array('Der Windrosenarmindex muss ein numerischer oder ein Richtungswert sein.',0),
22017 => array('Die Windrosendaten enthalten eine Richtung, die nicht aktiviert ist. Bitte berichtige, welche Label angezeigt werden sollen.',0),
22018 => array('Du hast fĆ¼r dieselbe Kompassrichtung zweimal Daten angegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1),
22019 => array('Der Index fĆ¼r eine Richtung muss zwischen 0 und 15 sein. Winkel dĆ¼rfen nicht fĆ¼r einen regelmƤƟigen Windplot angegeben werden, sondern entweder ein Index oder eine Kompassrichtung.',0),
22020 => array('Der Windrosenplot ist zu groƟ fĆ¼r die angegebene BildgrĆ¶ĆŸe. Benutze entweder WindrosePlot::SetSize(), um den Plot kleiner zu machen oder vergrĆ¶ĆŸere das Bild im ursprĆ¼nglichen Aufruf von WindroseGraph().',0),
22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0),
/*
** jpgraph_odometer
*/
 
13001 => array('Unbekannter Nadeltypstil (%d).',1),
13002 => array('Ein Wert fĆ¼r das Odometer (%f) ist auƟerhalb des angegebenen Bereichs [%f,%f]',3),
 
/*
** jpgraph_barcode
*/
 
1001 => array('Unbekannte Kodier-Specifikation: %s',1),
1002 => array('datenvalidierung schlug fehl. [%s] kann nicht mittels der Kodierung "%s" kodiert werden',2),
1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht mƶglich in Code 128',1),
1004 => array('Interner barcode Fehler. Unbekannter UPC-E Kodiertyp: %s',1),
1005 => array('Interner Fehler. Das Textzeichen-Tupel (%s, %s) kann nicht im Code-128 Zeichensatz C kodiert werden.',2),
1006 => array('Interner Kodierfehler fĆ¼r CODE 128. Es wurde versucht, CTRL in CHARSET != A zu kodieren.',0),
1007 => array('Interner Kodierfehler fĆ¼r CODE 128. Es wurde versucht, DEL in CHARSET != B zu kodieren.',0),
1008 => array('Interner Kodierfehler fĆ¼r CODE 128. Es wurde versucht, kleine Buchstaben in CHARSET != B zu kodieren.',0),
1009 => array('Kodieren mittels CODE 93 wird noch nicht unterstĆ¼tzt.',0),
1010 => array('Kodieren mittels POSTNET wird noch nicht unterstĆ¼tzt.',0),
1011 => array('Nicht untrstĆ¼tztes Barcode-Backend fĆ¼r den Typ %s',1),
 
/*
** PDF417
*/
 
26001 => array('PDF417: Die Anzahl der Spalten muss zwischen 1 und 30 sein.',0),
26002 => array('PDF417: Der Fehler-Level muss zwischen 0 und 8 sein.',0),
26003 => array('PDF417: UngĆ¼ltiges Format fĆ¼r Eingabedaten, um sie mit PDF417 zu kodieren.',0),
26004 => array('PDF417: die eigebenen Daten kƶnnen nicht mit Fehler-Level %d und %d spalten kodiert werden, weil daraus zu viele Symbole oder mehr als 90 Zeilen resultieren.',2),
26005 => array('PDF417: Die Datei "%s" kann nicht zum Schreiben geƶffnet werden.',1),
26006 => array('PDF417: Interner Fehler. Die Eingabedatendatei fĆ¼r PDF417-Cluster %d ist fehlerhaft.',1),
26007 => array('PDF417: Interner Fehler. GetPattern: UngĆ¼ltiger Code-Wert %d (Zeile %d)',2),
26008 => array('PDF417: Interner Fehler. Modus wurde nicht in der Modusliste!! Modus %d',1),
26009 => array('PDF417: Kodierfehler: UngĆ¼ltiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1),
26010 => array('PDF417: Interner Fehler: Keine Eingabedaten beim Dekodieren.',0),
26011 => array('PDF417: Kodierfehler. Numerisches Kodieren bei nicht-numerischen Daten nicht mƶglich.',0),
26012 => array('PDF417: Interner Fehler. Es wurden fĆ¼r den Binary-Kompressor keine Daten zum Dekodieren eingegeben.',0),
26013 => array('PDF417: Interner Fehler. Checksum Fehler. Koeffiziententabellen sind fehlerhaft.',0),
26014 => array('PDF417: Interner Fehler. Es wurden keine Daten zum Berechnen von Kodewƶrtern eingegeben.',0),
26015 => array('PDF417: Interner Fehler. Ein Eintrag 0 in die StatusĆ¼bertragungstabellen ist nicht NULL. Eintrag 1 = (%s)',1),
26016 => array('PDF417: Interner Fehler: Nichtregistrierter StatusĆ¼bertragungsmodus beim Dekodieren.',0),
 
 
);
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/lang/en.inc.php
New file
0,0 → 1,501
<?php
/*=======================================================================
// File: EN.INC.PHP
// Description: English language file for error messages
// Created: 2006-01-25
// Ver: $Id: en.inc.php 982 2008-03-24 11:51:47Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
// Note:
// Format of each error message is array(<error message>,<number of arguments>)
// The argument placeholders in the error strings are in printf() - format
 
$_jpg_messages = array(
 
/*
** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text
*/
10 => array('<table border="1"><tr><td style="color:darkred; font-size:1.2em;"><b>JpGraph Error:</b>
HTTP headers have already been sent.<br>Caused by output from file <b>%s</b> at line <b>%d</b>.</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>',2),
 
/*
** Setup errors
*/
11 => array('No path specified for CACHE_DIR. Please specify CACHE_DIR manually in jpg-config.inc',0),
12 => array('No path specified for TTF_DIR and path can not be determined automatically. Please specify TTF_DIR manually (in jpg-config.inc).',0),
13 => array('The installed PHP version (%s) is not compatible with this release of the library. The library requires at least PHP version %s',2),
/*
** jpgraph_bar
*/
 
2001 => array('Number of colors is not the same as the number of patterns in BarPlot::SetPattern()',0),
2002 => array('Unknown pattern specified in call to BarPlot::SetPattern()',0),
2003 => array('Number of X and Y points are not equal. Number of X-points: %d Number of Y-points: %d',2),
2004 => array('All values for a barplot must be numeric. You have specified value nr [%d] == %s',2),
2005 => array('You have specified an empty array for shadow colors in the bar plot.',0),
2006 => array('Unknown position for values on bars : %s',1),
2007 => array('Cannot create GroupBarPlot from empty plot array.',0),
2008 => array('Group bar plot element nbr %d is undefined or empty.',0),
2009 => array('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the GroupBar plot from an array of BarPlot or AccBarPlot objects. (Class = %s)',1),
2010 => array('Cannot create AccBarPlot from empty plot array.',0),
2011 => array('Acc bar plot element nbr %d is undefined or empty.',1),
2012 => array('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=%s)',1),
2013 => array('You have specified an empty array for shadow colors in the bar plot.',0),
2014 => array('Number of datapoints for each data set in accbarplot must be the same',0),
 
 
/*
** jpgraph_date
*/
 
3001 => array('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both',0),
 
/*
** jpgraph_error
*/
 
4002 => array('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3',0),
 
/*
** jpgraph_flags
*/
 
5001 => array('Unknown flag size (%d).',1),
5002 => array('Flag index %s does not exist.',1),
5003 => array('Invalid ordinal number (%d) specified for flag index.',1),
5004 => array('The (partial) country name %s does not have a corresponding flag image. The flag may still exist but under another name, e.g. instead of "usa" try "united states".',1),
 
 
/*
** jpgraph_gantt
*/
 
6001 => array('Internal error. Height for ActivityTitles is < 0',0),
6002 => array('You can\'t specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension.',0),
6003 => array('Invalid format for Constrain parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)',1),
6004 => array('Invalid format for Progress parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)',1),
6005 => array('SetScale() is not meaningful with Gantt charts.',0),
6006 => array('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]',0),
6007 => array('Sanity check for automatic Gantt chart size failed. Either the width (=%d) or height (=%d) is larger than MAX_GANTTIMG_SIZE. This could potentially be caused by a wrong date in one of the activities.',2),
6008 => array('You have specified a constrain from row=%d to row=%d which does not have any activity',2),
6009 => array('Unknown constrain type specified from row=%d to row=%d',2),
6010 => array('Illegal icon index for Gantt builtin icon [%d]',1),
6011 => array('Argument to IconImage must be string or integer',0),
6012 => array('Unknown type in Gantt object title specification',0),
6015 => array('Illegal vertical position %d',1),
6016 => array('Date string (%s) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30',1),
6017 => array('Unknown date format in GanttScale (%s).',1),
6018 => array('Interval for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an interval of %d minutes.',1),
6019 => array('The available width (%d) for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.',1),
6020 => array('Interval for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an interval of %d',1),
6021 => array('Unknown formatting style for week.',0),
6022 => array('Gantt scale has not been specified.',0),
6023 => array('If you display both hour and minutes the hour interval must be 1 (Otherwise it doesn\'t make sense to display minutes).',0),
6024 => array('CSIM Target must be specified as a string. Start of target is: %d',1),
6025 => array('CSIM Alt text must be specified as a string. Start of alt text is: %d',1),
6027 => array('Progress value must in range [0, 1]',0),
6028 => array('Specified height (%d) for gantt bar is out of range.',1),
6029 => array('Offset for vertical line must be in range [0,1]',0),
6030 => array('Unknown arrow direction for link.',0),
6031 => array('Unknown arrow type for link.',0),
6032 => array('Internal error: Unknown path type (=%d) specified for link.',1),
 
/*
** jpgraph_gradient
*/
 
7001 => array('Unknown gradient style (=%d).',1),
 
/*
** jpgraph_iconplot
*/
 
8001 => array('Mix value for icon must be between 0 and 100.',0),
8002 => array('Anchor position for icons must be one of "top", "bottom", "left", "right" or "center"',0),
8003 => array('It is not possible to specify both an image file and a country flag for the same icon.',0),
8004 => array('In order to use Country flags as icons you must include the "jpgraph_flags.php" file.',0),
 
/*
** jpgraph_imgtrans
*/
 
9001 => array('Value for image transformation out of bounds. Vanishing point on horizon must be specified as a value between 0 and 1.',0),
 
/*
** jpgraph_lineplot
*/
 
10001 => array('LinePlot::SetFilled() is deprecated. Use SetFillColor()',0),
10002 => array('Plot too complicated for fast line Stroke. Use standard Stroke()',0),
10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0),
/*
** jpgraph_log
*/
 
11001 => array('Your data contains non-numeric values.',0),
11002 => array('Negative data values can not be used in a log scale.',0),
11003 => array('Your data contains non-numeric values.',0),
11004 => array('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.',0),
11005 => array('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.',0),
 
/*
** jpgraph_mgraph
*/
 
/* 12001 => array("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 it is necessary to 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.",0),*/
 
12002 => array('Incorrect file name for MGraph::SetBackgroundImage() : %s Must have a valid image extension (jpg,gif,png) when using auto detection of image type',1),
12003 => array('Unknown file extension (%s) in MGraph::SetBackgroundImage() for filename: %s',2),
12004 => array('The image format of your background image (%s) is not supported in your system configuration. ',1),
12005 => array('Can\'t read background image: %s',1),
12006 => array('Illegal sizes specified for width or height when creating an image, (width=%d, height=%d)',2),
12007 => array('Argument to MGraph::Add() is not a valid GD image handle.',0),
12008 => array('Your PHP (and GD-lib) installation does not appear to support any known graphic formats.',0),
12009 => array('Your PHP installation does not support the chosen graphic format: %s',1),
12010 => array('Can\'t create or stream image to file %s Check that PHP has enough permission to write a file to the current directory.',1),
12011 => array('Can\'t create truecolor image. Check that you really have GD2 library installed.',0),
 
/*
** jpgraph_pie3d
*/
 
14001 => array('Pie3D::ShowBorder() . Deprecated function. Use Pie3D::SetEdge() to control the edges around slices.',0),
14002 => array('PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees.',0),
14003 => array('Internal assertion failed. Pie3D::Pie3DSlice',0),
14004 => array('Slice start angle must be between 0 and 360 degrees.',0),
14005 => array('Pie3D Internal error: Trying to wrap twice when looking for start index',0,),
14006 => array('Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking.',0),
14007 => array('Width for 3D Pie is 0. Specify a size > 0',0),
 
/*
** jpgraph_pie
*/
 
15001 => array('PiePLot::SetTheme() Unknown theme: %s',1),
15002 => array('Argument to PiePlot::ExplodeSlice() must be an integer',0),
15003 => array('Argument to PiePlot::Explode() must be an array with integer distances.',0),
15004 => array('Slice start angle must be between 0 and 360 degrees.',0),
15005 => array('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.',0),
15006 => array('PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]',0),
15007 => array('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.',0),
15008 => array('PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not %d).',1),
15009 => array('Illegal pie plot. Sum of all data is zero for Pie Plot',0),
15010 => array('Sum of all data is 0 for Pie.',0),
15011 => array('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.',0),
 
/*
** jpgraph_plotband
*/
 
16001 => array('Density for pattern must be between 1 and 100. (You tried %f)',1),
16002 => array('No positions specified for pattern.',0),
16003 => array('Unknown pattern specification (%d)',0),
16004 => array('Min value for plotband is larger than specified max value. Please correct.',0),
 
 
/*
** jpgraph_polar
*/
 
17001 => array('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).',0),
17002 => array('Unknown alignment specified for X-axis title. (%s)',1),
//17003 => array('Set90AndMargin() is not supported for polar graphs.',0),
17004 => array('Unknown scale type for polar graph. Must be "lin" or "log"',0),
 
/*
** jpgraph_radar
*/
 
18001 => array('Client side image maps not supported for RadarPlots.',0),
18002 => array('RadarGraph::SupressTickMarks() is deprecated. Use HideTickMarks() instead.',0),
18003 => array('Illegal scale for radarplot (%s). Must be \'lin\' or \'log\'',1),
18004 => array('Radar Plot size must be between 0.1 and 1. (Your value=%f)',1),
18005 => array('RadarPlot Unsupported Tick density: %d',1),
18006 => array('Minimum data %f (Radar plots should only be used when all data points > 0)',1),
18007 => array('Number of titles does not match number of points in plot.',0),
18008 => array('Each radar plot must have the same number of data points.',0),
 
/*
** jpgraph_regstat
*/
 
19001 => array('Spline: Number of X and Y coordinates must be the same',0),
19002 => array('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.',0),
19003 => array('Bezier: Number of X and Y coordinates must be the same',0),
 
/*
** jpgraph_scatter
*/
 
20001 => array('Fieldplots must have equal number of X and Y points.',0),
20002 => array('Fieldplots must have an angle specified for each X and Y points.',0),
20003 => array('Scatterplot must have equal number of X and Y points.',0),
 
/*
** jpgraph_stock
*/
 
21001 => array('Data values for Stock charts must contain an even multiple of %d data points.',1),
 
/*
** jpgraph_plotmark
*/
 
23001 => array('This marker "%s" does not exist in color with index: %d',2),
23002 => array('Mark color index too large for marker "%s"',1),
23003 => array('A filename must be specified if you set the mark type to MARK_IMG.',0),
 
/*
** jpgraph_utils
*/
 
24001 => array('FuncGenerator : No function specified. ',0),
24002 => array('FuncGenerator : Syntax error in function specification ',0),
24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0),
/*
** jpgraph
*/
 
25002 => array('Your PHP installation does not seem to have the required GD 2.x library enabled. Please see the PHP documentation, "Image" section. Make sure that "php_gd2.dll" statement is uncomment in the [modules] section in the php.ini file.',0),
25003 => array('General PHP error : At %s:%d : %s',3),
25004 => array('General PHP error : %s ',1),
25005 => array('Can\'t access PHP_SELF, PHP global variable. You can\'t run PHP from command line if you want to use the \'auto\' naming of cache or image files.',0),
25006 => array('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).',0),
25007 => array('You are trying to use the locale (%s) which your PHP installation does not support. Hint: Use \'\' to indicate the default locale for this geographic region.',1),
25008 => array('Image width/height argument in Graph::Graph() must be numeric',0),
25009 => array('You must specify what scale to use with a call to Graph::SetScale()',0),
 
25010 => array('Graph::Add() You tried to add a null plot to the graph.',0),
25011 => array('Graph::AddY2() You tried to add a null plot to the graph.',0),
25012 => array('Graph::AddYN() You tried to add a null plot to the graph.',0),
25013 => array('You can only add standard plots to multiple Y-axis',0),
25014 => array('Graph::AddText() You tried to add a null text to the graph.',0),
25015 => array('Graph::AddLine() You tried to add a null line to the graph.',0),
25016 => array('Graph::AddBand() You tried to add a null band to the graph.',0),
25017 => array('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 it is necessary to 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.',0),
25018 => array('Incorrect file name for Graph::SetBackgroundImage() : "%s" Must have a valid image extension (jpg,gif,png) when using auto detection of image type',1),
25019 => array('Unknown file extension (%s) in Graph::SetBackgroundImage() for filename: "%s"',2),
 
25020 => array('Graph::SetScale(): Specified Max value must be larger than the specified Min value.',0),
25021 => array('Unknown scale specification for Y-scale. (%s)',1),
25022 => array('Unknown scale specification for X-scale. (%s)',1),
25023 => array('Unsupported Y2 axis type: "%s" Must be one of (lin,log,int)',1),
25024 => array('Unsupported Y axis type: "%s" Must be one of (lin,log,int)',1),
25025 => array('Unsupported Tick density: %d',1),
25026 => array('Can\'t draw unspecified Y-scale. You have either: 1. Specified an Y axis for auto scaling but have not supplied any plots. 2. Specified a scale manually but have forgot to specify the tick steps',0),
25027 => array('Can\'t open cached CSIM "%s" for reading.',1),
25028 => array('Apache/PHP does not have permission to write to the CSIM cache directory (%s). Check permissions.',1),
25029 => array('Can\'t write CSIM "%s" for writing. Check free space and permissions.',1),
 
25030 => array('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().',0),
25031 => array('You must specify what scale to use with a call to Graph::SetScale().',0),
25032 => array('No plots for Y-axis nbr:%d',1),
25033 => array('',0),
25034 => array('Can\'t draw unspecified X-scale. No plots specified.',0),
25035 => array('You have enabled clipping. Clipping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (=%d degrees) or disable clipping.',1),
25036 => array('Unknown AxisStyle() : %s',1),
25037 => array('The image format of your background image (%s) is not supported in your system configuration. ',1),
25038 => array('Background image seems to be of different type (has different file extension) than specified imagetype. Specified: %s File: %s',2),
25039 => array('Can\'t read background image: "%s"',1),
 
25040 => array('It is not possible to specify both a background image and a background country flag.',0),
25041 => array('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.',0),
25042 => array('Unknown background image layout',0),
25043 => array('Unknown title background style.',0),
25044 => array('Cannot use auto scaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).',0),
25045 => array('Font families FF_HANDWRT and FF_BOOK are no longer available due to copyright problem with these fonts. Fonts can no longer be distributed with JpGraph. Please download fonts from http://corefonts.sourceforge.net/',0),
25046 => array('Specified TTF font family (id=%d) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/',1),
25047 => array('Style %s is not available for font family %s',2),
25048 => array('Unknown font style specification [%s].',1),
25049 => array('Font file "%s" is not readable or does not exist.',1),
 
25050 => array('First argument to Text::Text() must be a string.',0),
25051 => array('Invalid direction specified for text.',0),
25052 => array('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text',0),
25053 => array('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text',0),
25054 => array('Internal error: Unknown grid axis %s',1),
25055 => array('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead',0),
25056 => array('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.',0),
25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0),
25058 => array('Text label interval must be specified >= 1.',0),
25059 => array('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.',0),
 
25060 => array('Unknown alignment specified for X-axis title. (%s)',1),
25061 => array('Unknown alignment specified for Y-axis title. (%s)',1),
25062 => array('Labels at an angle are not supported on Y-axis',0),
25063 => array('Ticks::SetPrecision() is deprecated. Use Ticks::SetLabelFormat() (or Ticks::SetFormatCallback()) instead',0),
25064 => array('Minor or major step size is 0. Check that you haven\'t got an accidental SetTextTicks(0) in your code. 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',0),
25065 => array('Tick positions must be specified as an array()',0),
25066 => array('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.',0),
25067 => array('Your manually specified scale and ticks is not correct. The scale seems to be too small to hold any of the specified tick marks.',0),
25068 => array('A plot has an illegal scale. This could for example be that you are trying to use text auto scaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only \'-\' or \'x\')',0),
25069 => array('Grace must be larger then 0',0),
25070 => array('Either X or Y data arrays contains non-numeric values. Check that the data is really specified as numeric data and not as strings. It is an error to specify data for example as \'-2345.2\' (using quotes).',0),
25071 => array('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.',0),
25072 => array('You have specified a max value with SetAutoMax() which is smaller than the minimum value used for the scale. This is not possible.',0),
25073 => array('Internal error. Integer scale algorithm comparison out of bound (r=%f)',1),
25074 => array('Internal error. The scale range is negative (%f) [for %s scale] This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the auto scaling to fail.',2),
25075 => array('Can\'t automatically determine ticks since min==max.',0),
25077 => array('Adjustment factor for color must be > 0',0),
25078 => array('Unknown color: %s',1),
25079 => array('Unknown color specification: %s, size=%d',2),
 
25080 => array('Alpha parameter for color must be between 0.0 and 1.0',0),
25081 => array('Selected graphic format is either not supported or unknown [%s]',1),
25082 => array('Illegal sizes specified for width or height when creating an image, (width=%d, height=%d)',2),
25083 => array('Illegal image size when copying image. Size for copied to image is 1 pixel or less.',0),
25084 => array('Failed to create temporary GD canvas. Possible Out of memory problem.',0),
25085 => array('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.',0),
25086 => array('You only seem to have GD 1.x installed. To enable Alphablending requires GD 2.x or higher. Please install GD or make sure the constant USE_GD2 is specified correctly to reflect your installation. By default it tries to auto detect what version of GD you have installed. On some very rare occasions it may falsely detect GD2 where only GD1 is installed. You must then set USE_GD2 to false.',0),
25087 => array('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.',0),
25088 => array('You have a misconfigured GD font support. The call to imagefontwidth() fails.',0),
25089 => array('You have a misconfigured GD font support. The call to imagefontheight() fails.',0),
 
25090 => array('Unknown direction specified in call to StrokeBoxedText() [%s]',1),
25091 => array('Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead.',0),
25092 => array('There is either a configuration problem with TrueType or a problem reading font file "%s" Make sure file exists and is in a readable place for the HTTP process. (If \'basedir\' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try upgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library.',1),
25093 => array('Can not read font file "%s" in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.',1),
25094 => array('Direction for text most be given as an angle between 0 and 90.',0),
25095 => array('Unknown font font family specification. ',0),
25096 => array('Can\'t allocate any more colors.',0),
25097 => array('Color specified as empty string in PushColor().',0),
25098 => array('Negative Color stack index. Unmatched call to PopColor()',0),
25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0),
 
25100 => array('Problem with color palette and your GD setup. Please disable anti-aliasing or use GD2 with true-color. If you have GD2 library installed please make sure that you have set the USE_GD2 constant to true and truecolor is enabled.',0),
25101 => array('Illegal numeric argument to SetLineStyle(): (%d)',1),
25102 => array('Illegal string argument to SetLineStyle(): %s',1),
25103 => array('Illegal argument to SetLineStyle %s',1),
25104 => array('Unknown line style: %s',1),
25105 => array('NULL data specified for a filled polygon. Check that your data is not NULL.',0),
25106 => array('Image::FillToBorder : Can not allocate more colors',0),
25107 => array('Can\'t write to file "%s". Check that the process running PHP has enough permission.',1),
25108 => array('Can\'t stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP.',0),
25109 => array('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.',0),
 
25110 => array('Your PHP installation does not support the chosen graphic format: %s',1),
25111 => array('Can\'t delete cached image %s. Permission problem?',1),
25112 => array('Cached imagefile (%s) has file date in the future.',1),
25113 => array('Can\'t delete cached image "%s". Permission problem?',1),
25114 => array('PHP has not enough permissions to write to the cache file "%s". Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.',1),
25115 => array('Can\'t set permission for cached image "%s". Permission problem?',1),
25116 => array('Cant open file from cache "%s"',1),
25117 => array('Can\'t open cached image "%s" for reading.',1),
25118 => array('Can\'t create directory "%s". Make sure PHP has write permission to this directory.',1),
25119 => array('Can\'t set permissions for "%s". Permission problems?',1),
 
25120 => array('Position for legend must be given as percentage in range 0-1',0),
25121 => array('Empty input data array specified for plot. Must have at least one data point.',0),
25122 => array('Stroke() must be implemented by concrete subclass to class Plot',0),
25123 => array('You can\'t use a text X-scale with specified X-coords. Use a "int" or "lin" scale instead.',0),
25124 => array('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)',0),
25125 => array('Illegal direction for static line',0),
25126 => array('Can\'t create truecolor image. Check that the GD2 library is properly setup with PHP.',0),
25127 => array('The library has been configured for automatic encoding conversion of Japanese fonts. This requires that PHP has the mb_convert_encoding() function. Your PHP installation lacks this function (PHP needs the "--enable-mbstring" when compiled).',0),
 
/*
**---------------------------------------------------------------------------------------------
** Pro-version strings
**---------------------------------------------------------------------------------------------
*/
 
/*
** jpgraph_table
*/
 
27001 => array('GTextTable: Invalid argument to Set(). Array argument must be 2 dimensional',0),
27002 => array('GTextTable: Invalid argument to Set()',0),
27003 => array('GTextTable: Wrong number of arguments to GTextTable::SetColor()',0),
27004 => array('GTextTable: Specified cell range to be merged is not valid.',0),
27005 => array('GTextTable: Cannot merge already merged cells in the range: (%d,%d) to (%d,%d)',4),
27006 => array('GTextTable: Column argument = %d is outside specified table size.',1),
27007 => array('GTextTable: Row argument = %d is outside specified table size.',1),
27008 => array('GTextTable: Column and row size arrays must match the dimensions of the table',0),
27009 => array('GTextTable: Number of table columns or rows are 0. Make sure Init() or Set() is called.',0),
27010 => array('GTextTable: No alignment specified in call to SetAlign()',0),
27011 => array('GTextTable: Unknown alignment specified in SetAlign(). Horizontal=%s, Vertical=%s',2),
27012 => array('GTextTable: Internal error. Invalid alignment specified =%s',1),
27013 => array('GTextTable: Argument to FormatNumber() must be a string.',0),
27014 => array('GTextTable: Table is not initilaized with either a call to Set() or Init()',0),
27015 => array('GTextTable: Cell image constrain type must be TIMG_WIDTH or TIMG_HEIGHT',0),
 
/*
** jpgraph_windrose
*/
 
22001 => array('Total percentage for all windrose legs in a windrose plot can not exceed 100%% !\n(Current max is: %d)',1),
22002 => array('Graph is too small to have a scale. Please make the graph larger.',0),
22004 => array('Label specification for windrose directions must have 16 values (one for each compass direction).',0),
22005 => array('Line style for radial lines must be on of ("solid","dotted","dashed","longdashed") ',0),
22006 => array('Illegal windrose type specified.',0),
22007 => array('To few values for the range legend.',0),
22008 => array('Internal error: Trying to plot free Windrose even though type is not a free windrose',0),
22009 => array('You have specified the same direction twice, once with an angle and once with a compass direction (%f degrees)',0),
22010 => array('Direction must either be a numeric value or one of the 16 compass directions',0),
22011 => array('Windrose index must be numeric or direction label. You have specified index=%d',1),
22012 => array('Windrose radial axis specification contains a direction which is not enabled.',0),
22013 => array('You have specified the look&feel for the same compass direction twice, once with text and once with index (Index=%d)',1),
22014 => array('Index for compass direction must be between 0 and 15.',0),
22015 => array('You have specified an undefined Windrose plot type.',0),
22016 => array('Windrose leg index must be numeric or direction label.',0),
22017 => array('Windrose data contains a direction which is not enabled. Please adjust what labels are displayed.',0),
22018 => array('You have specified data for the same compass direction twice, once with text and once with index (Index=%d)',1),
22019 => array('Index for direction must be between 0 and 15. You can\'t specify angles for a Regular Windplot, only index and compass directions.',0),
22020 => array('Windrose plot is too large to fit the specified Graph size. Please use WindrosePlot::SetSize() to make the plot smaller or increase the size of the Graph in the initial WindroseGraph() call.',0),
22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0),
 
/*
** jpgraph_odometer
*/
 
13001 => array('Unknown needle style (%d).',1),
13002 => array('Value for odometer (%f) is outside specified scale [%f,%f]',3),
 
/*
** jpgraph_barcode
*/
 
1001 => array('Unknown encoder specification: %s',1),
1002 => array('Data validation failed. Can\'t encode [%s] using encoding "%s"',2),
1003 => array('Internal encoding error. Trying to encode %s is not possible in Code 128',1),
1004 => array('Internal barcode error. Unknown UPC-E encoding type: %s',1),
1005 => array('Internal error. Can\'t encode character tuple (%s, %s) in Code-128 charset C',2),
1006 => array('Internal encoding error for CODE 128. Trying to encode control character in CHARSET != A',0),
1007 => array('Internal encoding error for CODE 128. Trying to encode DEL in CHARSET != B',0),
1008 => array('Internal encoding error for CODE 128. Trying to encode small letters in CHARSET != B',0),
1009 => array('Encoding using CODE 93 is not yet supported.',0),
1010 => array('Encoding using POSTNET is not yet supported.',0),
1011 => array('Non supported barcode backend for type %s',1),
 
/*
** PDF417
*/
 
26001 => array('PDF417: Number of Columns must be >= 1 and <= 30',0),
26002 => array('PDF417: Error level must be between 0 and 8',0),
26003 => array('PDF417: Invalid format for input data to encode with PDF417',0),
26004 => array('PDF417: Can\'t encode given data with error level %d and %d columns since it results in too many symbols or more than 90 rows.',2),
26005 => array('PDF417: Can\'t open file "%s" for writing',1),
26006 => array('PDF417: Internal error. Data files for PDF417 cluster %d is corrupted.',1),
26007 => array('PDF417: Internal error. GetPattern: Illegal Code Value = %d (row=%d)',2),
26008 => array('PDF417: Internal error. Mode not found in mode list!! mode=%d',1),
26009 => array('PDF417: Encode error: Illegal character. Can\'t encode character with ASCII code=%d',1),
26010 => array('PDF417: Internal error: No input data in decode.',0),
26011 => array('PDF417: Encoding error. Can\'t use numeric encoding on non-numeric data.',0),
26012 => array('PDF417: Internal error. No input data to decode for Binary compressor.',0),
26013 => array('PDF417: Internal error. Checksum error. Coefficient tables corrupted.',0),
26014 => array('PDF417: Internal error. No data to calculate codewords on.',0),
26015 => array('PDF417: Internal error. State transition table entry 0 is NULL. Entry 1 = (%s)',1),
26016 => array('PDF417: Internal error: Unrecognized state transition mode in decode.',0),
 
 
);
 
/*
** EOF
*/
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/lang/prod.inc.php
New file
0,0 → 1,354
<?php
/*=======================================================================
// File: PROD.INC.PHP
// Description: Special localization file with the same error messages
// for all errors.
// Created: 2006-02-18
// Ver: $Id: prod.inc.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
// The single error message for all errors
DEFINE('DEFAULT_ERROR_MESSAGE','We are sorry but the system could not generate the requested image. Please contact site support to resolve this problem. Problem no: #');
 
// Note: Format of each error message is array(<error message>,<number of arguments>)
$_jpg_messages = array(
 
/*
** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text
*/
10 => array('<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b>
HTTP headers have already been sent.<br>Caused by output from file <b>%s</b> at line <b>%d</b>.</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>',2),
 
 
11 => array(DEFAULT_ERROR_MESSAGE.'11',0),
12 => array(DEFAULT_ERROR_MESSAGE.'12',0),
13 => array(DEFAULT_ERROR_MESSAGE.'13',0),
2001 => array(DEFAULT_ERROR_MESSAGE.'2001',0),
2002 => array(DEFAULT_ERROR_MESSAGE.'2002',0),
2003 => array(DEFAULT_ERROR_MESSAGE.'2003',0),
2004 => array(DEFAULT_ERROR_MESSAGE.'2004',0),
2005 => array(DEFAULT_ERROR_MESSAGE.'2005',0),
2006 => array(DEFAULT_ERROR_MESSAGE.'2006',0),
2007 => array(DEFAULT_ERROR_MESSAGE.'2007',0),
2008 => array(DEFAULT_ERROR_MESSAGE.'2008',0),
2009 => array(DEFAULT_ERROR_MESSAGE.'2009',0),
2010 => array(DEFAULT_ERROR_MESSAGE.'2010',0),
2011 => array(DEFAULT_ERROR_MESSAGE.'2011',0),
2012 => array(DEFAULT_ERROR_MESSAGE.'2012',0),
2013 => array(DEFAULT_ERROR_MESSAGE.'2013',0),
2014 => array(DEFAULT_ERROR_MESSAGE.'2014',0),
3001 => array(DEFAULT_ERROR_MESSAGE.'3001',0),
4002 => array(DEFAULT_ERROR_MESSAGE.'4002',0),
5001 => array(DEFAULT_ERROR_MESSAGE.'5001',0),
5002 => array(DEFAULT_ERROR_MESSAGE.'5002',0),
5003 => array(DEFAULT_ERROR_MESSAGE.'5003',0),
5004 => array(DEFAULT_ERROR_MESSAGE.'5004',0),
6001 => array(DEFAULT_ERROR_MESSAGE.'6001',0),
6002 => array(DEFAULT_ERROR_MESSAGE.'6002',0),
6003 => array(DEFAULT_ERROR_MESSAGE.'6003',0),
6004 => array(DEFAULT_ERROR_MESSAGE.'6004',0),
6005 => array(DEFAULT_ERROR_MESSAGE.'6005',0),
6006 => array(DEFAULT_ERROR_MESSAGE.'6006',0),
6007 => array(DEFAULT_ERROR_MESSAGE.'6007',0),
6008 => array(DEFAULT_ERROR_MESSAGE.'6008',0),
6009 => array(DEFAULT_ERROR_MESSAGE.'6009',0),
6010 => array(DEFAULT_ERROR_MESSAGE.'6010',0),
6011 => array(DEFAULT_ERROR_MESSAGE.'6011',0),
6012 => array(DEFAULT_ERROR_MESSAGE.'6012',0),
6015 => array(DEFAULT_ERROR_MESSAGE.'6015',0),
6016 => array(DEFAULT_ERROR_MESSAGE.'6016',0),
6017 => array(DEFAULT_ERROR_MESSAGE.'6017',0),
6018 => array(DEFAULT_ERROR_MESSAGE.'6018',0),
6019 => array(DEFAULT_ERROR_MESSAGE.'6019',0),
6020 => array(DEFAULT_ERROR_MESSAGE.'6020',0),
6021 => array(DEFAULT_ERROR_MESSAGE.'6021',0),
6022 => array(DEFAULT_ERROR_MESSAGE.'6022',0),
6023 => array(DEFAULT_ERROR_MESSAGE.'6023',0),
6024 => array(DEFAULT_ERROR_MESSAGE.'6024',0),
6025 => array(DEFAULT_ERROR_MESSAGE.'6025',0),
6027 => array(DEFAULT_ERROR_MESSAGE.'6027',0),
6028 => array(DEFAULT_ERROR_MESSAGE.'6028',0),
6029 => array(DEFAULT_ERROR_MESSAGE.'6029',0),
6030 => array(DEFAULT_ERROR_MESSAGE.'6030',0),
6031 => array(DEFAULT_ERROR_MESSAGE.'6031',0),
6032 => array(DEFAULT_ERROR_MESSAGE.'6032',0),
7001 => array(DEFAULT_ERROR_MESSAGE.'7001',0),
8001 => array(DEFAULT_ERROR_MESSAGE.'8001',0),
8002 => array(DEFAULT_ERROR_MESSAGE.'8002',0),
8003 => array(DEFAULT_ERROR_MESSAGE.'8003',0),
8004 => array(DEFAULT_ERROR_MESSAGE.'8004',0),
9001 => array(DEFAULT_ERROR_MESSAGE.'9001',0),
10001 => array(DEFAULT_ERROR_MESSAGE.'10001',0),
10002 => array(DEFAULT_ERROR_MESSAGE.'10002',0),
11001 => array(DEFAULT_ERROR_MESSAGE.'11001',0),
11002 => array(DEFAULT_ERROR_MESSAGE.'11002',0),
11003 => array(DEFAULT_ERROR_MESSAGE.'11003',0),
11004 => array(DEFAULT_ERROR_MESSAGE.'11004',0),
11005 => array(DEFAULT_ERROR_MESSAGE.'11005',0),
12001 => array(DEFAULT_ERROR_MESSAGE.'12001',0),
12002 => array(DEFAULT_ERROR_MESSAGE.'12002',0),
12003 => array(DEFAULT_ERROR_MESSAGE.'12003',0),
12004 => array(DEFAULT_ERROR_MESSAGE.'12004',0),
12005 => array(DEFAULT_ERROR_MESSAGE.'12005',0),
12006 => array(DEFAULT_ERROR_MESSAGE.'12006',0),
12007 => array(DEFAULT_ERROR_MESSAGE.'12007',0),
12008 => array(DEFAULT_ERROR_MESSAGE.'12008',0),
12009 => array(DEFAULT_ERROR_MESSAGE.'12009',0),
12010 => array(DEFAULT_ERROR_MESSAGE.'12010',0),
12011 => array(DEFAULT_ERROR_MESSAGE.'12011',0),
12012 => array(DEFAULT_ERROR_MESSAGE.'12012',0),
14001 => array(DEFAULT_ERROR_MESSAGE.'14001',0),
14002 => array(DEFAULT_ERROR_MESSAGE.'14002',0),
14003 => array(DEFAULT_ERROR_MESSAGE.'14003',0),
14004 => array(DEFAULT_ERROR_MESSAGE.'14004',0),
14005 => array(DEFAULT_ERROR_MESSAGE.'14005',0),
14006 => array(DEFAULT_ERROR_MESSAGE.'14006',0),
14007 => array(DEFAULT_ERROR_MESSAGE.'14007',0),
15001 => array(DEFAULT_ERROR_MESSAGE.'15001',0),
15002 => array(DEFAULT_ERROR_MESSAGE.'15002',0),
15003 => array(DEFAULT_ERROR_MESSAGE.'15003',0),
15004 => array(DEFAULT_ERROR_MESSAGE.'15004',0),
15005 => array(DEFAULT_ERROR_MESSAGE.'15005',0),
15006 => array(DEFAULT_ERROR_MESSAGE.'15006',0),
15007 => array(DEFAULT_ERROR_MESSAGE.'15007',0),
15008 => array(DEFAULT_ERROR_MESSAGE.'15008',0),
15009 => array(DEFAULT_ERROR_MESSAGE.'15009',0),
15010 => array(DEFAULT_ERROR_MESSAGE.'15010',0),
15011 => array(DEFAULT_ERROR_MESSAGE.'15011',0),
16001 => array(DEFAULT_ERROR_MESSAGE.'16001',0),
16002 => array(DEFAULT_ERROR_MESSAGE.'16002',0),
16003 => array(DEFAULT_ERROR_MESSAGE.'16003',0),
16004 => array(DEFAULT_ERROR_MESSAGE.'16004',0),
17001 => array(DEFAULT_ERROR_MESSAGE.'17001',0),
17002 => array(DEFAULT_ERROR_MESSAGE.'17002',0),
17004 => array(DEFAULT_ERROR_MESSAGE.'17004',0),
18001 => array(DEFAULT_ERROR_MESSAGE.'18001',0),
18002 => array(DEFAULT_ERROR_MESSAGE.'18002',0),
18003 => array(DEFAULT_ERROR_MESSAGE.'18003',0),
18004 => array(DEFAULT_ERROR_MESSAGE.'18004',0),
18005 => array(DEFAULT_ERROR_MESSAGE.'18005',0),
18006 => array(DEFAULT_ERROR_MESSAGE.'18006',0),
18007 => array(DEFAULT_ERROR_MESSAGE.'18007',0),
18008 => array(DEFAULT_ERROR_MESSAGE.'18008',0),
19001 => array(DEFAULT_ERROR_MESSAGE.'19001',0),
19002 => array(DEFAULT_ERROR_MESSAGE.'19002',0),
19003 => array(DEFAULT_ERROR_MESSAGE.'19003',0),
20001 => array(DEFAULT_ERROR_MESSAGE.'20001',0),
20002 => array(DEFAULT_ERROR_MESSAGE.'20002',0),
20003 => array(DEFAULT_ERROR_MESSAGE.'20003',0),
21001 => array(DEFAULT_ERROR_MESSAGE.'21001',0),
23001 => array(DEFAULT_ERROR_MESSAGE.'23001',0),
23002 => array(DEFAULT_ERROR_MESSAGE.'23002',0),
23003 => array(DEFAULT_ERROR_MESSAGE.'23003',0),
24001 => array(DEFAULT_ERROR_MESSAGE.'24001',0),
24002 => array(DEFAULT_ERROR_MESSAGE.'24002',0),
24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0),
25001 => array(DEFAULT_ERROR_MESSAGE.'25001',0),
25002 => array(DEFAULT_ERROR_MESSAGE.'25002',0),
25003 => array(DEFAULT_ERROR_MESSAGE.'25003',0),
25004 => array(DEFAULT_ERROR_MESSAGE.'25004',0),
25005 => array(DEFAULT_ERROR_MESSAGE.'25005',0),
25006 => array(DEFAULT_ERROR_MESSAGE.'25006',0),
25007 => array(DEFAULT_ERROR_MESSAGE.'25007',0),
25008 => array(DEFAULT_ERROR_MESSAGE.'25008',0),
25009 => array(DEFAULT_ERROR_MESSAGE.'25009',0),
25010 => array(DEFAULT_ERROR_MESSAGE.'25010',0),
25011 => array(DEFAULT_ERROR_MESSAGE.'25011',0),
25012 => array(DEFAULT_ERROR_MESSAGE.'25012',0),
25013 => array(DEFAULT_ERROR_MESSAGE.'25013',0),
25014 => array(DEFAULT_ERROR_MESSAGE.'25014',0),
25015 => array(DEFAULT_ERROR_MESSAGE.'25015',0),
25016 => array(DEFAULT_ERROR_MESSAGE.'25016',0),
25017 => array(DEFAULT_ERROR_MESSAGE.'25017',0),
25018 => array(DEFAULT_ERROR_MESSAGE.'25018',0),
25019 => array(DEFAULT_ERROR_MESSAGE.'25019',0),
25020 => array(DEFAULT_ERROR_MESSAGE.'25020',0),
25021 => array(DEFAULT_ERROR_MESSAGE.'25021',0),
25022 => array(DEFAULT_ERROR_MESSAGE.'25022',0),
25023 => array(DEFAULT_ERROR_MESSAGE.'25023',0),
25024 => array(DEFAULT_ERROR_MESSAGE.'25024',0),
25025 => array(DEFAULT_ERROR_MESSAGE.'25025',0),
25026 => array(DEFAULT_ERROR_MESSAGE.'25026',0),
25027 => array(DEFAULT_ERROR_MESSAGE.'25027',0),
25028 => array(DEFAULT_ERROR_MESSAGE.'25028',0),
25029 => array(DEFAULT_ERROR_MESSAGE.'25029',0),
25030 => array(DEFAULT_ERROR_MESSAGE.'25030',0),
25031 => array(DEFAULT_ERROR_MESSAGE.'25031',0),
25032 => array(DEFAULT_ERROR_MESSAGE.'25032',0),
25033 => array(DEFAULT_ERROR_MESSAGE.'25033',0),
25034 => array(DEFAULT_ERROR_MESSAGE.'25034',0),
25035 => array(DEFAULT_ERROR_MESSAGE.'25035',0),
25036 => array(DEFAULT_ERROR_MESSAGE.'25036',0),
25037 => array(DEFAULT_ERROR_MESSAGE.'25037',0),
25038 => array(DEFAULT_ERROR_MESSAGE.'25038',0),
25039 => array(DEFAULT_ERROR_MESSAGE.'25039',0),
25040 => array(DEFAULT_ERROR_MESSAGE.'25040',0),
25041 => array(DEFAULT_ERROR_MESSAGE.'25041',0),
25042 => array(DEFAULT_ERROR_MESSAGE.'25042',0),
25043 => array(DEFAULT_ERROR_MESSAGE.'25043',0),
25044 => array(DEFAULT_ERROR_MESSAGE.'25044',0),
25045 => array(DEFAULT_ERROR_MESSAGE.'25045',0),
25046 => array(DEFAULT_ERROR_MESSAGE.'25046',0),
25047 => array(DEFAULT_ERROR_MESSAGE.'25047',0),
25048 => array(DEFAULT_ERROR_MESSAGE.'25048',0),
25049 => array(DEFAULT_ERROR_MESSAGE.'25049',0),
25050 => array(DEFAULT_ERROR_MESSAGE.'25050',0),
25051 => array(DEFAULT_ERROR_MESSAGE.'25051',0),
25052 => array(DEFAULT_ERROR_MESSAGE.'25052',0),
25053 => array(DEFAULT_ERROR_MESSAGE.'25053',0),
25054 => array(DEFAULT_ERROR_MESSAGE.'25054',0),
25055 => array(DEFAULT_ERROR_MESSAGE.'25055',0),
25056 => array(DEFAULT_ERROR_MESSAGE.'25056',0),
25057 => array(DEFAULT_ERROR_MESSAGE.'25057',0),
25058 => array(DEFAULT_ERROR_MESSAGE.'25058',0),
25059 => array(DEFAULT_ERROR_MESSAGE.'25059',0),
25060 => array(DEFAULT_ERROR_MESSAGE.'25060',0),
25061 => array(DEFAULT_ERROR_MESSAGE.'25061',0),
25062 => array(DEFAULT_ERROR_MESSAGE.'25062',0),
25063 => array(DEFAULT_ERROR_MESSAGE.'25063',0),
25064 => array(DEFAULT_ERROR_MESSAGE.'25064',0),
25065 => array(DEFAULT_ERROR_MESSAGE.'25065',0),
25066 => array(DEFAULT_ERROR_MESSAGE.'25066',0),
25067 => array(DEFAULT_ERROR_MESSAGE.'25067',0),
25068 => array(DEFAULT_ERROR_MESSAGE.'25068',0),
25069 => array(DEFAULT_ERROR_MESSAGE.'25069',0),
25070 => array(DEFAULT_ERROR_MESSAGE.'25070',0),
25071 => array(DEFAULT_ERROR_MESSAGE.'25071',0),
25072 => array(DEFAULT_ERROR_MESSAGE.'25072',0),
25073 => array(DEFAULT_ERROR_MESSAGE.'25073',0),
25074 => array(DEFAULT_ERROR_MESSAGE.'25074',0),
25075 => array(DEFAULT_ERROR_MESSAGE.'25075',0),
25077 => array(DEFAULT_ERROR_MESSAGE.'25077',0),
25078 => array(DEFAULT_ERROR_MESSAGE.'25078',0),
25079 => array(DEFAULT_ERROR_MESSAGE.'25079',0),
25080 => array(DEFAULT_ERROR_MESSAGE.'25080',0),
25081 => array(DEFAULT_ERROR_MESSAGE.'25081',0),
25082 => array(DEFAULT_ERROR_MESSAGE.'25082',0),
25083 => array(DEFAULT_ERROR_MESSAGE.'25083',0),
25084 => array(DEFAULT_ERROR_MESSAGE.'25084',0),
25085 => array(DEFAULT_ERROR_MESSAGE.'25085',0),
25086 => array(DEFAULT_ERROR_MESSAGE.'25086',0),
25087 => array(DEFAULT_ERROR_MESSAGE.'25087',0),
25088 => array(DEFAULT_ERROR_MESSAGE.'25088',0),
25089 => array(DEFAULT_ERROR_MESSAGE.'25089',0),
25090 => array(DEFAULT_ERROR_MESSAGE.'25090',0),
25091 => array(DEFAULT_ERROR_MESSAGE.'25091',0),
25092 => array(DEFAULT_ERROR_MESSAGE.'25092',0),
25093 => array(DEFAULT_ERROR_MESSAGE.'25093',0),
25094 => array(DEFAULT_ERROR_MESSAGE.'25094',0),
25095 => array(DEFAULT_ERROR_MESSAGE.'25095',0),
25096 => array(DEFAULT_ERROR_MESSAGE.'25096',0),
25097 => array(DEFAULT_ERROR_MESSAGE.'25097',0),
25098 => array(DEFAULT_ERROR_MESSAGE.'25098',0),
25099 => array(DEFAULT_ERROR_MESSAGE.'25099',0),
25100 => array(DEFAULT_ERROR_MESSAGE.'25100',0),
25101 => array(DEFAULT_ERROR_MESSAGE.'25101',0),
25102 => array(DEFAULT_ERROR_MESSAGE.'25102',0),
25103 => array(DEFAULT_ERROR_MESSAGE.'25103',0),
25104 => array(DEFAULT_ERROR_MESSAGE.'25104',0),
25105 => array(DEFAULT_ERROR_MESSAGE.'25105',0),
25106 => array(DEFAULT_ERROR_MESSAGE.'25106',0),
25107 => array(DEFAULT_ERROR_MESSAGE.'25107',0),
25108 => array(DEFAULT_ERROR_MESSAGE.'25108',0),
25109 => array(DEFAULT_ERROR_MESSAGE.'25109',0),
25110 => array(DEFAULT_ERROR_MESSAGE.'25110',0),
25111 => array(DEFAULT_ERROR_MESSAGE.'25111',0),
25112 => array(DEFAULT_ERROR_MESSAGE.'25112',0),
25113 => array(DEFAULT_ERROR_MESSAGE.'25113',0),
25114 => array(DEFAULT_ERROR_MESSAGE.'25114',0),
25115 => array(DEFAULT_ERROR_MESSAGE.'25115',0),
25116 => array(DEFAULT_ERROR_MESSAGE.'25116',0),
25117 => array(DEFAULT_ERROR_MESSAGE.'25117',0),
25118 => array(DEFAULT_ERROR_MESSAGE.'25118',0),
25119 => array(DEFAULT_ERROR_MESSAGE.'25119',0),
25120 => array(DEFAULT_ERROR_MESSAGE.'25120',0),
25121 => array(DEFAULT_ERROR_MESSAGE.'25121',0),
25122 => array(DEFAULT_ERROR_MESSAGE.'25122',0),
25123 => array(DEFAULT_ERROR_MESSAGE.'25123',0),
25124 => array(DEFAULT_ERROR_MESSAGE.'25124',0),
25125 => array(DEFAULT_ERROR_MESSAGE.'25125',0),
25126 => array(DEFAULT_ERROR_MESSAGE.'25126',0),
25127 => array(DEFAULT_ERROR_MESSAGE.'25126',0),
24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0),
24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0),
24005 => array(DEFAULT_ERROR_MESSAGE.'24005',0),
24006 => array(DEFAULT_ERROR_MESSAGE.'24006',0),
24007 => array(DEFAULT_ERROR_MESSAGE.'24007',0),
24008 => array(DEFAULT_ERROR_MESSAGE.'24008',0),
24009 => array(DEFAULT_ERROR_MESSAGE.'24009',0),
24010 => array(DEFAULT_ERROR_MESSAGE.'24010',0),
24011 => array(DEFAULT_ERROR_MESSAGE.'24011',0),
24012 => array(DEFAULT_ERROR_MESSAGE.'24012',0),
24013 => array(DEFAULT_ERROR_MESSAGE.'24013',0),
24014 => array(DEFAULT_ERROR_MESSAGE.'24014',0),
24015 => array(DEFAULT_ERROR_MESSAGE.'24015',0),
22001 => array(DEFAULT_ERROR_MESSAGE.'22001',0),
22002 => array(DEFAULT_ERROR_MESSAGE.'22002',0),
22004 => array(DEFAULT_ERROR_MESSAGE.'22004',0),
22005 => array(DEFAULT_ERROR_MESSAGE.'22005',0),
22006 => array(DEFAULT_ERROR_MESSAGE.'22006',0),
22007 => array(DEFAULT_ERROR_MESSAGE.'22007',0),
22008 => array(DEFAULT_ERROR_MESSAGE.'22008',0),
22009 => array(DEFAULT_ERROR_MESSAGE.'22009',0),
22010 => array(DEFAULT_ERROR_MESSAGE.'22010',0),
22011 => array(DEFAULT_ERROR_MESSAGE.'22011',0),
22012 => array(DEFAULT_ERROR_MESSAGE.'22012',0),
22013 => array(DEFAULT_ERROR_MESSAGE.'22013',0),
22014 => array(DEFAULT_ERROR_MESSAGE.'22014',0),
22015 => array(DEFAULT_ERROR_MESSAGE.'22015',0),
22016 => array(DEFAULT_ERROR_MESSAGE.'22016',0),
22017 => array(DEFAULT_ERROR_MESSAGE.'22017',0),
22018 => array(DEFAULT_ERROR_MESSAGE.'22018',0),
22019 => array(DEFAULT_ERROR_MESSAGE.'22019',0),
22020 => array(DEFAULT_ERROR_MESSAGE.'22020',0),
13001 => array(DEFAULT_ERROR_MESSAGE.'13001',0),
13002 => array(DEFAULT_ERROR_MESSAGE.'13002',0),
1001 => array(DEFAULT_ERROR_MESSAGE.'1001',0),
1002 => array(DEFAULT_ERROR_MESSAGE.'1002',0),
1003 => array(DEFAULT_ERROR_MESSAGE.'1003',0),
1004 => array(DEFAULT_ERROR_MESSAGE.'1004',0),
1005 => array(DEFAULT_ERROR_MESSAGE.'1005',0),
1006 => array(DEFAULT_ERROR_MESSAGE.'1006',0),
1007 => array(DEFAULT_ERROR_MESSAGE.'1007',0),
1008 => array(DEFAULT_ERROR_MESSAGE.'1008',0),
1009 => array(DEFAULT_ERROR_MESSAGE.'1009',0),
1010 => array(DEFAULT_ERROR_MESSAGE.'1010',0),
1011 => array(DEFAULT_ERROR_MESSAGE.'1011',0),
26001 => array(DEFAULT_ERROR_MESSAGE.'26001',0),
26002 => array(DEFAULT_ERROR_MESSAGE.'26002',0),
26003 => array(DEFAULT_ERROR_MESSAGE.'26003',0),
26004 => array(DEFAULT_ERROR_MESSAGE.'26004',0),
26005 => array(DEFAULT_ERROR_MESSAGE.'26005',0),
26006 => array(DEFAULT_ERROR_MESSAGE.'26006',0),
26007 => array(DEFAULT_ERROR_MESSAGE.'26007',0),
26008 => array(DEFAULT_ERROR_MESSAGE.'26008',0),
26009 => array(DEFAULT_ERROR_MESSAGE.'26009',0),
26010 => array(DEFAULT_ERROR_MESSAGE.'26010',0),
26011 => array(DEFAULT_ERROR_MESSAGE.'26011',0),
26012 => array(DEFAULT_ERROR_MESSAGE.'26012',0),
26013 => array(DEFAULT_ERROR_MESSAGE.'26013',0),
26014 => array(DEFAULT_ERROR_MESSAGE.'26014',0),
26015 => array(DEFAULT_ERROR_MESSAGE.'26015',0),
26016 => array(DEFAULT_ERROR_MESSAGE.'26016',0),
 
27001 => array(DEFAULT_ERROR_MESSAGE.'27001',0),
27002 => array(DEFAULT_ERROR_MESSAGE.'27002',0),
27003 => array(DEFAULT_ERROR_MESSAGE.'27003',0),
27004 => array(DEFAULT_ERROR_MESSAGE.'27004',0),
27005 => array(DEFAULT_ERROR_MESSAGE.'27005',0),
27006 => array(DEFAULT_ERROR_MESSAGE.'27006',0),
27007 => array(DEFAULT_ERROR_MESSAGE.'27007',0),
27008 => array(DEFAULT_ERROR_MESSAGE.'27008',0),
27009 => array(DEFAULT_ERROR_MESSAGE.'27009',0),
27010 => array(DEFAULT_ERROR_MESSAGE.'27010',0),
27011 => array(DEFAULT_ERROR_MESSAGE.'27011',0),
27012 => array(DEFAULT_ERROR_MESSAGE.'27012',0),
27013 => array(DEFAULT_ERROR_MESSAGE.'27013',0),
27014 => array(DEFAULT_ERROR_MESSAGE.'27014',0),
27015 => array(DEFAULT_ERROR_MESSAGE.'27015',0),
);
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_diamonds.inc.php
New file
0,0 → 1,177
<?php
//=======================================================================
// File: IMGDATA_DIAMONDS.INC
// Description: Base64 encoded images for diamonds
// Created: 2003-03-20
// Ver: $Id: imgdata_diamonds.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class ImgData_Diamonds extends ImgData {
var $name = 'Diamonds';
var $an = array(MARK_IMG_DIAMOND =>'imgdata');
var $colors = array('lightblue','darkblue','gray',
'blue','pink','purple','red','yellow');
var $index = array('lightblue' =>7,'darkblue'=>2,'gray'=>6,
'blue'=>4,'pink'=>1,'purple'=>5,'red'=>0,'yellow'=>3);
 
var $maxidx = 7 ;
var $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'.
'==' ;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_stock.php
New file
0,0 → 1,182
<?php
/*=======================================================================
// File: JPGRAPH_STOCK.PHP
// Description: Stock plot extension for JpGraph
// Created: 2003-01-27
// Ver: $Id: jpgraph_stock.php 1079 2008-09-19 15:46:20Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
//===================================================
// CLASS StockPlot
//===================================================
class StockPlot extends Plot {
var $iTupleSize = 4;
var $iWidth=9;
var $iEndLines=1;
var $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);
}
// Stroke stock plot
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]),$n);
//("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\" alt=\"$sval\" ";
}
$this->csimareas.= " />\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 {
var $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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_imgtrans.php
New file
0,0 → 1,223
<?php
//=======================================================================
// File: JPGRAPH_IMGTRANS.PHP
// Description: Extension for JpGraph to do some simple img transformations
// Created: 2003-09-06
// Ver: $Id: jpgraph_imgtrans.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
//------------------------------------------------------------------------
// Class ImgTrans
// Perform some simple image transformations.
//------------------------------------------------------------------------
class ImgTrans {
var $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);
 
}
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_line.php
New file
0,0 → 1,635
<?php
/*=======================================================================
// File: JPGRAPH_LINE.PHP
// Description: Line plot extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_line.php 982 2008-03-24 11:51:47Z 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{
var $filled=false;
var $fill_color='blue';
var $mark=null;
var $step_style=false, $center=false;
var $line_style=1; // Default to solid
var $filledAreas = array(); // array of arrays(with min,max,col,filled in them)
var $barcenter=false; // When we mix line and bar. Should we center the line in the bar.
var $fillFromMin = false ;
var $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100;
var $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,$this->legendcsimwintarget);
}
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,$this->legendcsimwintarget);
}
else {
$graph->legend->Add($this->legend,
$this->color,$this->mark,$this->line_style,
$this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
}
}
}
 
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()');
return;
}
++$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]) ) {
if( !empty($this->csimwintargets[$pnts]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]);
}
else {
$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();
}
}
 
 
}
} // Class
 
 
//===================================================
// CLASS AccLinePlot
// Description:
//===================================================
class AccLinePlot extends Plot {
var $plots=null,$nbrplots=0,$numpoints=0;
var $iStartEndZero=true;
//---------------
// CONSTRUCTOR
function AccLinePlot($plots) {
$this->plots = $plots;
$this->nbrplots = count($plots);
$this->numpoints = $plots[0]->numpoints;
 
// Verify that all plots have the same number of data points
for( $i=1; $i < $this->nbrplots; ++$i ) {
if( $plots[$i]->numpoints != $this->numpoints ) {
JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0)
}
}
 
for($i=0; $i < $this->nbrplots; ++$i ) {
$this->LineInterpolate($this->plots[$i]->coords[0]);
}
}
 
//---------------
// PUBLIC METHODS
function Legend(&$graph) {
$n=count($this->plots);
for($i=0; $i < $n; ++$i )
$this->plots[$i]->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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_radar.php
New file
0,0 → 1,667
<?php
/*=======================================================================
// File: JPGRAPH_RADAR.PHP
// Description: Radar plot extension for JpGraph
// Created: 2001-02-04
// Ver: $Id: jpgraph_radar.php 857 2007-03-23 19:03:13Z 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 LinearTicks {
//---------------
// CONSTRUCTOR
function RadarLinearTicks() {
// Empty
}
 
//---------------
// PUBLIC METHODS
 
// TODO: Add argument grid
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);
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 Axis {
var $title_color="navy";
var $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($l) {
$this->ticks_label = $l;
}
// 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);
// 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) {
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;
 
// Around 3 a'clock
if( $aAxisAngle>=7*M_PI/4 || $aAxisAngle <= M_PI/4 ) $dx=-0.15; // Small trimming to make the dist to the axis more even
// Around 12 a'clock
if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dx=($aAxisAngle-M_PI/4)*2/M_PI;
// Around 9 a'clock
if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dx=1;
// Around 6 a'clock
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/12 ) $dy=(0.5-$aAxisAngle*2/M_PI);
if( $aAxisAngle<=M_PI/4 && $aAxisAngle > M_PI/12) $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 {
//------------
// CONSTRUCTOR
function RadarGrid() {
}
 
//----------------
// 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 {
var $data=array();
var $fill=false, $fill_color=array(200,170,180);
var $color=array(0,0,0);
var $legend="";
var $weight=1;
var $linestyle='solid';
var $mark=null;
//---------------
// 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 {
var $posx;
var $posy;
var $len;
var $plots=null, $axis_title=null;
var $grid,$axis=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) {
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) {
$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() {
$min=$this->plots[0]->Min();
$max=$this->plots[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->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') ) {
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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_error.php
New file
0,0 → 1,156
<?php
/*=======================================================================
// File: JPGRAPH_ERROR.PHP
// Description: Error plot extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_error.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
//===================================================
// CLASS ErrorPlot
// Description: Error plot with min/max value for
// each datapoint
//===================================================
class ErrorPlot extends Plot {
var $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 {
var $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 {
var $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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_pushpins.inc.php
New file
0,0 → 1,517
<?php
//=======================================================================
// File: IMGDATA_PUSHPINS.INC
// Description: Base64 encoded images for pushpins
// Created: 2003-03-20
// Ver: $Id: imgdata_pushpins.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class ImgData_PushPins extends ImgData {
var $name = 'Push pins';
var $an = array(MARK_IMG_PUSHPIN => 'imgdata_small',
MARK_IMG_SPUSHPIN => 'imgdata_small',
MARK_IMG_LPUSHPIN => 'imgdata_large');
 
var $colors = array('blue','green','orange','pink','red');
var $index = array('red' => 0, 'orange' => 1, 'pink' => 2, 'blue' => 3, 'green' => 4 ) ;
var $maxidx = 4 ;
var $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' ;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_gradient.php
New file
0,0 → 1,424
<?php
/*=======================================================================
// File: JPGRAPH_GRADIENT.PHP
// Description: Create a color gradient
// Created: 2003-02-01
// Ver: $Id: jpgraph_gradient.php 946 2007-10-19 22:14:00Z 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 {
var $img=null;
var $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 = ceil(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 = ceil(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 = ceil(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 = ceil(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 = ceil(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 = ceil(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 = ceil(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 = ceil(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 = floor($pts[$i]);
$y = floor($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
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_errhandler.inc.php
New file
0,0 → 1,277
<?php
//=======================================================================
// File: JPGRAPH_ERRHANDLER.PHP
// Description: Error handler class together with handling of localized
// error messages. All localized error messages are stored
// in a separate file under the "lang/" subdirectory.
// Created: 2006-09-24
// Ver: $Id: jpgraph_errhandler.inc.php 974 2008-03-09 15:30:01Z ljp $
//
// Copyright 2006 (c) Aditus Consulting. All rights reserved.
//========================================================================
 
 
// Since the error handler needs to be accessed from anywhere this must be
// made a global variable.
GLOBAL $__jpg_err;
GLOBAL $__jpg_err_locale ;
$__jpg_err_locale = DEFAULT_ERR_LOCALE;
 
// Handles the retrieval of localized error messages
class ErrMsgText {
var $lt=NULL;
function ErrMsgText() {
GLOBAL $__jpg_err_locale;
$file = 'lang/'.$__jpg_err_locale.'.inc.php';
 
// If the chosen locale doesn't exist try english
if( !file_exists(dirname(__FILE__).'/'.$file) ) {
$__jpg_err_locale = 'en';
}
 
$file = 'lang/'.$__jpg_err_locale.'.inc.php';
if( !file_exists(dirname(__FILE__).'/'.$file) ) {
die('Chosen locale file ("'.$file.'") for error messages does not exist or is not readable for the PHP process. Please make sure that the file exists and that the file permissions are such that the PHP process is allowed to read this file.');
}
require($file);
$this->lt = $_jpg_messages;
}
 
function Get($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) {
GLOBAL $__jpg_err_locale;
if( !isset($this->lt[$errnbr]) ) {
return 'Internal error: The specified error message ('.$errnbr.') does not exist in the chosen locale ('.$__jpg_err_locale.')';
}
$ea = $this->lt[$errnbr];
$j=0;
if( $a1 !== null ) {
$argv[$j++] = $a1;
if( $a2 !== null ) {
$argv[$j++] = $a2;
if( $a3 !== null ) {
$argv[$j++] = $a3;
if( $a4 !== null ) {
$argv[$j++] = $a4;
if( $a5 !== null ) {
$argv[$j++] = $a5;
}
}
}
}
}
$numargs = $j;
if( $ea[1] != $numargs ) {
// Error message argument count do not match.
// Just return the error message without arguments.
return $ea[0];
}
switch( $numargs ) {
case 1:
$msg = sprintf($ea[0],$argv[0]);
break;
case 2:
$msg = sprintf($ea[0],$argv[0],$argv[1]);
break;
case 3:
$msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2]);
break;
case 4:
$msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3]);
break;
case 5:
$msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3],$argv[4]);
break;
case 0:
default:
$msg = sprintf($ea[0]);
break;
}
return $msg;
}
}
 
//
// A wrapper class that is used to access the specified error object
// (to hide the global error parameter and avoid having a GLOBAL directive
// in all methods.
//
class JpGraphError {
function Install($aErrObject) {
GLOBAL $__jpg_err;
$__jpg_err = $aErrObject;
}
function SetErrLocale($aLoc) {
GLOBAL $__jpg_err_locale ;
$__jpg_err_locale = $aLoc;
}
function Raise($aMsg,$aHalt=true){
GLOBAL $__jpg_err;
$tmp = new $__jpg_err;
$tmp->Raise($aMsg,$aHalt);
}
function RaiseL($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) {
GLOBAL $__jpg_err;
$t = new ErrMsgText();
$msg = $t->Get($errnbr,$a1,$a2,$a3,$a4,$a5);
$tmp = new $__jpg_err;
$tmp->Raise($msg);
}
}
 
// The default trivial text error handler.
class JpGraphErrObject {
 
var $iTitle = "JpGraph Error";
var $iDest = false;
 
function JpGraphErrObject() {
// Empty. Reserved for future use
}
 
function SetTitle($aTitle) {
$this->iTitle = $aTitle;
}
 
function SetStrokeDest($aDest) {
$this->iDest = $aDest;
}
 
// If aHalt is true then execution can't continue. Typical used for fatal errors.
function Raise($aMsg,$aHalt=true) {
$aMsg = $this->iTitle.' '.$aMsg."\n";
if ($this->iDest) {
$f = @fopen($this->iDest,'a');
if( $f ) {
@fwrite($f,$aMsg);
@fclose($f);
}
}
else {
echo $aMsg;
}
if( $aHalt )
die();
}
}
 
//==============================================================
// An image based error handler
//==============================================================
class JpGraphErrObjectImg extends JpGraphErrObject {
 
function Raise($aMsg,$aHalt=true) {
$img_iconerror =
'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaV'.
'BMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'.
'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpY'.
'iYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'.
'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'.
'IAAAsSAdLdfvwAAAAHdElNRQfTBgISOCqusfs5AAABLUlEQVR4'.
'2tWV3XKCMBBGWfkranCIVClKLd/7P2Q3QsgCxjDTq+6FE2cPH+'.
'xJ0Ogn2lQbsT+Wrs+buAZAV4W5T6Bs0YXBBwpKgEuIu+JERAX6'.
'wM2rHjmDdEITmsQEEmWADgZm6rAjhXsoMGY9B/NZBwJzBvn+e3'.
'wHntCAJdGu9SviwIwoZVDxPB9+Rc0TSEbQr0j3SA1gwdSn6Db0'.
'6Tm1KfV6yzWGQO7zdpvyKLKBDmRFjzeB3LYgK7r6A/noDAfjtS'.
'IXaIzbJSv6WgUebTMV4EoRB8a2mQiQjgtF91HdKDKZ1gtFtQjk'.
'YcWaR5OKOhkYt+ZsTFdJRfPAApOpQYJTNHvCRSJR6SJngQadfc'.
'vd69OLMddVOPCGVnmrFD8bVYd3JXfxXPtLR/+mtv59/ALWiiMx'.
'qL72fwAAAABJRU5ErkJggg==' ;
 
if( function_exists("imagetypes") )
$supported = imagetypes();
else
$supported = 0;
 
if( !function_exists('imagecreatefromstring') )
$supported = 0;
 
if( ob_get_length() || headers_sent() || !($supported & IMG_PNG) ) {
// Special case for headers already sent or that the installation doesn't support
// the PNG format (which the error icon is encoded in).
// Dont return an image since it can't be displayed
die($this->iTitle.' '.$aMsg);
}
 
$aMsg = wordwrap($aMsg,55);
$lines = substr_count($aMsg,"\n");
 
// Create the error icon GD
$erricon = Image::CreateFromString(base64_decode($img_iconerror));
 
// Create an image that contains the error text.
$w=400;
$h=100 + 15*max(0,$lines-3);
 
$img = new Image($w,$h);
 
// Drop shadow
$img->SetColor("gray");
$img->FilledRectangle(5,5,$w-1,$h-1,10);
$img->SetColor("gray:0.7");
$img->FilledRectangle(5,5,$w-3,$h-3,10);
// Window background
$img->SetColor("lightblue");
$img->FilledRectangle(1,1,$w-5,$h-5);
$img->CopyCanvasH($img->img,$erricon,5,30,0,0,40,40);
 
// Window border
$img->SetColor("black");
$img->Rectangle(1,1,$w-5,$h-5);
$img->Rectangle(0,0,$w-4,$h-4);
// Window top row
$img->SetColor("darkred");
for($y=3; $y < 18; $y += 2 )
$img->Line(1,$y,$w-6,$y);
 
// "White shadow"
$img->SetColor("white");
 
// Left window edge
$img->Line(2,2,2,$h-5);
$img->Line(2,2,$w-6,2);
 
// "Gray button shadow"
$img->SetColor("darkgray");
 
// Gray window shadow
$img->Line(2,$h-6,$w-5,$h-6);
$img->Line(3,$h-7,$w-5,$h-7);
 
// Window title
$m = floor($w/2-5);
$l = 100;
$img->SetColor("lightgray:1.3");
$img->FilledRectangle($m-$l,2,$m+$l,16);
 
// Stroke text
$img->SetColor("darkred");
$img->SetFont(FF_FONT2,FS_BOLD);
$img->StrokeText($m-50,15,$this->iTitle);
$img->SetColor("black");
$img->SetFont(FF_FONT1,FS_NORMAL);
$txt = new Text($aMsg,52,25);
$txt->Align("left","top");
$txt->Stroke($img);
if ($this->iDest) {
$img->Stream($this->iDest);
} else {
$img->Headers();
$img->Stream();
}
if( $aHalt )
die();
}
}
 
// Install the default error handler in a global accessible variable
if( USE_IMAGE_ERROR_HANDLER ) {
$__jpg_err = "JpGraphErrObjectImg";
}
else {
$__jpg_err = "JpGraphErrObject";
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags.dat
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags.dat
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_plotband.php
New file
0,0 → 1,634
<?php
//=======================================================================
// File: JPGRAPH_PLOTBAND.PHP
// Description: PHP4 Graph Plotting library. Extension module.
// Created: 2004-02-18
// Ver: $Id: jpgraph_plotband.php 782 2006-10-08 08:09:02Z 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 {
var $x,$y,$w,$h;
var $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 {
var $color;
var $weight;
var $rect=null;
var $doframe=true;
var $linespacing; // Line spacing in pixels
var $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 {
var $linespacing=10; // Line spacing in pixels
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 {
var $linespacing; // Line spacing in pixels
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 {
var $linespacing; // Line spacing in pixels
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 {
var $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 {
var $vert=null;
var $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 {
var $left=null;
var $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 {
var $prect=null;
var $depth;
var $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;
}
// 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);
}
}
}
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_pie3d.php
New file
0,0 → 1,923
<?php
/*=======================================================================
// File: JPGRAPH_PIE3D.PHP
// Description: 3D Pie plot extension for JpGraph
// Created: 2001-03-24
// Ver: $Id: jpgraph_pie3d.php 955 2007-11-17 11:41:42Z 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 {
var $labelhintcolor="red",$showlabelhint=true;
var $angle=50;
var $edgecolor="", $edgeweight=1;
var $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($aTargets,$aAlts='',$aWinTargets='') {
$this->csimtargets = $aTargets;
$this->csimwintargets = $aWinTargets;
$this->csimalts = $aAlts;
}
 
// 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 AddSliceToCSIM($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->csimtargets[$i]) ) {
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\"";
if( !empty($this->csimwintargets[$i]) ) {
$this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
}
if( !empty($this->csimalts[$i]) ) {
$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
$this->csimareas .= "alt=\"$tmp\" title=\"$tmp\" ";
}
$this->csimareas .= " />\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
$img->SetFont($this->value->ff,$this->value->fs);
$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->AddSliceToCSIM($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->Pos($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.
$img->SetFont($this->value->ff,$this->value->fs,$this->value->fsize);
$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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_bar.php
New file
0,0 → 1,1036
<?php
/*=======================================================================
// File: JPGRAPH_BAR.PHP
// Description: Bar plot extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_bar.php 1013 2008-06-27 06:33:43Z 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 {
var $width=0.4; // in percent of major ticks
var $abswidth=-1; // Width in absolute pixels
var $fill=false,$fill_color="lightblue"; // Default is to fill with light blue
var $ybase=0; // Bars start at 0
var $align="center";
var $grad=false,$grad_style=1;
var $grad_fromcolor=array(50,50,200),$grad_tocolor=array(255,255,255);
var $bar_shadow=false;
var $bar_shadow_color="black";
var $bar_shadow_hsize=3,$bar_shadow_vsize=3;
var $valuepos='top';
var $iPattern=-1,$iPatternDensity=80,$iPatternColor='black';
//---------------
// 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,$this->legendcsimwintarget);
}
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,$this->legendcsimwintarget);
}
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,$this->legendcsimwintarget);
}
else {
$graph->legend->Add($this->legend,$this->fill_color,"",0,
$this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
}
}
}
 
// 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( is_a($this,'AccBarPlot') || is_a($this,'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($aFromColor,$aToColor=null,$aStyle=null) {
$this->grad = true;
$this->grad_fromcolor = $aFromColor;
$this->grad_tocolor = $aToColor;
$this->grad_style = $aStyle;
}
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::RaiseL(2001);//('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 = 95;
break;
case PATTERN_STRIPE2:
$aPatternValue= 5;
$aDensity = 85;
break;
default:
JpGraphError::RaiseL(2002);//('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::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;
$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 potential pattern array to avoid doing the count for each iteration
if( is_array($this->iPattern) ) {
$np = count($this->iPattern);
}
$grad = null;
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] === '' )
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 ) {
if( $grad === null )
$grad = new Gradient($img);
if( is_array($this->grad_fromcolor) ) {
// The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
// then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
// an array to specify both (from, to style) for each individual bar. The way to know the difference is
// to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
// triple.
$ng = count($this->grad_fromcolor);
if( $ng === 3 ) {
if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) {
// RGB Triple
$fromcolor = $this->grad_fromcolor;
$tocolor = $this->grad_tocolor;
$style = $this->grad_style;
}
}
else {
$fromcolor = $this->grad_fromcolor[$i % $ng][0];
$tocolor = $this->grad_fromcolor[$i % $ng][1];
$style = $this->grad_fromcolor[$i % $ng][2];
}
$grad->FilledRectangle($pts[2],$pts[3],
$pts[6],$pts[7],
$fromcolor,$tocolor,$style);
}
else {
$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::RaiseL(2004,$i,$val);
//('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::RaiseL(2005);//('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;
$this->value->SetMargin(5);
 
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');
}
else {
if( $val < 0 ) {
$this->value->SetMargin(-5);
$y=$pts[1];
$this->value->SetAlign('center','bottom');
}
else {
$this->value->SetAlign('center','bottom');
}
 
}
$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 {
if( $val < 0 ) {
$this->value->SetAlign('center','bottom');
}
else {
$this->value->SetAlign('center','top');
}
}
$this->value->SetMargin(-5);
$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::RaiseL(2006,$this->valuepos);
//('Unknown position for values on bars :'.$this->valuepos);
}
if( !empty($this->csimtargets[$i]) ) {
// 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]);
}
$this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" ';
$this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\"";
 
if( !empty($this->csimwintargets[$i]) ) {
$this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
}
 
$sval='';
if( !empty($this->csimalts[$i]) ) {
$sval=sprintf($this->csimalts[$i],$this->coords[0][$i]);
$this->csimareas .= " title=\"$sval\" alt=\"$sval\" ";
}
$this->csimareas .= " />\n";
}
}
return true;
}
} // Class
 
//===================================================
// CLASS GroupBarPlot
// Description: Produce grouped bar plots
//===================================================
class GroupBarPlot extends BarPlot {
var $plots=array(), $nbrplots=0;
var $numpoints;
//---------------
// CONSTRUCTOR
function GroupBarPlot($plots) {
$this->width=0.5;
$this->plots = $plots;
$this->nbrplots = count($plots);
if( $this->nbrplots < 1 ) {
JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.');
}
for($i=0; $i < $this->nbrplots; ++$i ) {
if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty.");
}
}
$this->numpoints = $plots[0]->numpoints;
}
 
//---------------
// PUBLIC METHODS
function Legend(&$graph) {
$n = count($this->plots);
for($i=0; $i < $n; ++$i) {
$c = get_class($this->plots[$i]);
if( !is_a($this->plots[$i],'BarPlot') ) {
JpGraphError::RaiseL(2009,$c);//('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 {
var $plots=null,$nbrplots=0,$numpoints=0;
//---------------
// CONSTRUCTOR
function AccBarPlot($plots) {
$this->plots = $plots;
$this->nbrplots = count($plots);
if( $this->nbrplots < 1 ) {
JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.');
}
for($i=0; $i < $this->nbrplots; ++$i ) {
if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
JpGraphError::RaiseL(2011,$i);//("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( !is_a($this->plots[$i],'BarPlot') ) {
JpGraphError::RaiseL(2012,$c);//('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::RaiseL(2013);//('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);
$fillcolor = $this->plots[$j]->fill_color[$i % $numcolors];
// If the bar is specified to be non filled then the fill color is false
if( $fillcolor !== false )
$img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]);
}
else {
$fillcolor = $this->plots[$j]->fill_color;
if( $fillcolor !== false )
$img->SetColor($this->plots[$j]->fill_color);
}
if( $fillcolor !== false )
$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]."\" ";
 
if( ! empty($this->plots[$j]->csimwintargets[$i]) ) {
$this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$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->SetLineWeight($this->plots[$j]->line_weight);
$img->Polygon($pts);
$img->SetLineWeight(1);
}
// 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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_led.php
New file
0,0 → 1,316
<?php
//=======================================================================
// File: JPGRAPH_LED.PHP
// Description: Module to generate Dotted LED-like digits
// Created: 2006-11-26
// Ver: $Id: jpgraph_led.php 1077 2008-09-19 15:44:30Z ljp $
//
// Copyright 2006 (c) Aditus Consulting. All rights reserved.
//
// Changed: 2007-08-06 by Alexander Kurochkin (inspector@list.ru)
// Added: Decipher 4-bit mask.
// Added: Chars Latin > 'L', Cyrilic, other symbols and special symbols for
// simulation some latin and cyrilic chars.
// Added: New Color schemas.
// Deleted: Some minor bugs (StrokeNumber first parameter may be eq empty string,
// false or null - added check see line 294;
// change color schema check for easy maintenance: 291;
// change check on key exist in chars array: moved from StrokeNumber
// function to _GetLED: 251;
//
//========================================================================
 
// Samples for troubled chars: "ƔĀ” Ƙ\r ƙ\r ƛ| ƞƎ ƌ\r >\n< W\r"
// Ɣ Ƙ ƙ ƛ ƞ ƌ Ɔ W
 
//----------------------------------------------------------------------------
// Each character is encoded line by line with the "On"-LEDs corresponding to
// a '1' in the bianry mask of 4 bits.
//
// 4-bit mask:
//
// 0 ____
// 1 ___x
// 2 __x_
// 3 __xx
// 4 _x__
// 5 _x_x
// 6 _xx_
// 7 _xxx
// 8 x___
// 9 x__x
// 10 x_x_
// 11 x_xx
// 12 xx__
// 13 xx_x
// 14 xxx_
// 15 xxxx
//----------------------------------------------------------------------------
 
// Constants for color schema. See definition of iColorSchema below
DEFINE('LEDC_RED', 0);
DEFINE('LEDC_GREEN', 1);
DEFINE('LEDC_BLUE', 2);
DEFINE('LEDC_YELLOW', 3);
DEFINE('LEDC_GRAY', 4);
DEFINE('LEDC_CHOCOLATE', 5);
DEFINE('LEDC_PERU', 6);
DEFINE('LEDC_GOLDENROD', 7);
DEFINE('LEDC_KHAKI', 8);
DEFINE('LEDC_OLIVE', 9);
DEFINE('LEDC_LIMEGREEN', 10);
DEFINE('LEDC_FORESTGREEN', 11);
DEFINE('LEDC_TEAL', 12);
DEFINE('LEDC_STEELBLUE', 13);
DEFINE('LEDC_NAVY', 14);
DEFINE('LEDC_INVERTGRAY', 15);
// ! It correlate with two-dimensional array $iColorSchema
 
//========================================================================
// CLASS DigitalLED74
// Description:
// Construct a number as an image that looks like LED numbers in a
// 7x4 digital matrix
//========================================================================
class DigitalLED74
{
var $iLED_X = 4, $iLED_Y=7,
 
// fg-up, fg-down, bg
$iColorSchema = array(
LEDC_RED => array('red','darkred:0.9','red:0.3'),// 0
LEDC_GREEN => array('green','darkgreen','green:0.3'),// 1
LEDC_BLUE => array('lightblue:0.9','darkblue:0.85','darkblue:0.7'),// 2
LEDC_YELLOW => array('yellow','yellow:0.4','yellow:0.3'),// 3
LEDC_GRAY => array('gray:1.4','darkgray:0.85','darkgray:0.7'),
LEDC_CHOCOLATE => array('chocolate','chocolate:0.7','chocolate:0.5'),
LEDC_PERU => array('peru:0.95','peru:0.6','peru:0.5'),
LEDC_GOLDENROD => array('goldenrod','goldenrod:0.6','goldenrod:0.5'),
LEDC_KHAKI => array('khaki:0.7','khaki:0.4','khaki:0.3'),
LEDC_OLIVE => array('#808000','#808000:0.7','#808000:0.6'),
LEDC_LIMEGREEN => array('limegreen:0.9','limegreen:0.5','limegreen:0.4'),
LEDC_FORESTGREEN => array('forestgreen','forestgreen:0.7','forestgreen:0.5'),
LEDC_TEAL => array('teal','teal:0.7','teal:0.5'),
LEDC_STEELBLUE => array('steelblue','steelblue:0.65','steelblue:0.5'),
LEDC_NAVY => array('navy:1.3','navy:0.95','navy:0.8'),//14
LEDC_INVERTGRAY => array('darkgray','lightgray:1.5','white')//15
),
 
$iLEDSpec = array(
0 => array(6,9,11,15,13,9,6),
//0 => array(6,9,9,9,9,9,6),
//0 => array(15,9,9,9,9,9,15),
1 => array(2,6,10,2,2,2,2),
2 => array(6,9,1,2,4,8,15),
3 => array(6,9,1,6,1,9,6),
4 => array(1,3,5,9,15,1,1),
5 => array(15,8,8,14,1,9,6),
6 => array(6,8,8,14,9,9,6),
7 => array(15,1,1,2,4,4,4),
8 => array(6,9,9,6,9,9,6),
9 => array(6,9,9,7,1,1,6),
'!' => array(4,4,4,4,4,0,4),
'?' => array(6,9,1,2,2,0,2),
'#' => array(0,9,15,9,15,9,0),
'@' => array(6,9,11,11,10,9,6),
'-' => array(0,0,0,15,0,0,0),
'_' => array(0,0,0,0,0,0,15),
'=' => array(0,0,15,0,15,0,0),
'+' => array(0,0,4,14,4,0,0),
'|' => array(4,4,4,4,4,4,4), //vertical line, used for simulate rus 'ƛ'
',' => array(0,0,0,0,0,12,4),
'.' => array(0,0,0,0,0,12,12),
':' => array(12,12,0,0,0,12,12),
';' => array(12,12,0,0,0,12,4),
'[' => array(3,2,2,2,2,2,3),
']' => array(12,4,4,4,4,4,12),
'(' => array(1,2,2,2,2,2,1),
')' => array(8,4,4,4,4,4,8),
'{' => array(3,2,2,6,2,2,3),
'}' => array(12,4,4,6,4,4,12),
'<' => array(1,2,4,8,4,2,1),
'>' => array(8,4,2,1,2,4,8),
'*' => array(9,6,15,6,9,0,0),
'"' => array(10,10,0,0,0,0,0),
'\'' => array(4,4,0,0,0,0,0),
'`' => array(4,2,0,0,0,0,0),
'~' => array(13,11,0,0,0,0,0),
'^' => array(4,10,0,0,0,0,0),
'\\' => array(8,8,4,6,2,1,1),
'/' => array(1,1,2,6,4,8,8),
'%' => array(1,9,2,6,4,9,8),
'&' => array(0,4,10,4,11,10,5),
'$' => array(2,7,8,6,1,14,4),
' ' => array(0,0,0,0,0,0,0),
'Ā•' => array(0,0,6,6,0,0,0), //149
'Ā°' => array(14,10,14,0,0,0,0), //176
'Ā†' => array(4,4,14,4,4,4,4), //134
'Ā‡' => array(4,4,14,4,14,4,4), //135
'Ā±' => array(0,4,14,4,0,14,0), //177
'Ā‰' => array(0,4,2,15,2,4,0), //137 show right arrow
'Ā™' => array(0,2,4,15,4,2,0), //156 show left arrow
'Ā”' => array(0,0,8,8,0,0,0), //159 show small hi-stick - that need for simulate rus 'Ɣ'
"\t" => array(8,8,8,0,0,0,0), //show hi-stick - that need for simulate rus 'Ɠ'
"\r" => array(8,8,8,8,8,8,8), //vertical line - that need for simulate 'M', 'W' and rus 'ƌ','Ƙ' ,'ƙ'
"\n" => array(15,15,15,15,15,15,15), //fill up - that need for simulate rus 'Ɔ'
"Ā„" => array(10,5,10,5,10,5,10), //chess
"Āµ" => array(15,0,15,0,15,0,15), //4 horizontal lines
// latin
'A' => array(6,9,9,15,9,9,9),
'B' => array(14,9,9,14,9,9,14),
'C' => array(6,9,8,8,8,9,6),
'D' => array(14,9,9,9,9,9,14),
'E' => array(15,8,8,14,8,8,15),
'F' => array(15,8,8,14,8,8,8),
'G' => array(6,9,8,8,11,9,6),
'H' => array(9,9,9,15,9,9,9),
'I' => array(14,4,4,4,4,4,14),
'J' => array(15,1,1,1,1,9,6),
'K' => array(8,9,10,12,12,10,9),
'L' => array(8,8,8,8,8,8,15),
'M' => array(8,13,10,8,8,8,8),// need to add \r
'N' => array(9,9,13,11,9,9,9),
//'O' => array(0,6,9,9,9,9,6),
'O' => array(6,9,9,9,9,9,6),
'P' => array(14,9,9,14,8,8,8),
'Q' => array(6,9,9,9,13,11,6),
'R' => array(14,9,9,14,12,10,9),
'S' => array(6,9,8,6,1,9,6),
'T' => array(14,4,4,4,4,4,4),
'U' => array(9,9,9,9,9,9,6),
'V' => array(0,0,0,10,10,10,4),
'W' => array(8,8,8,8,10,13,8),// need to add \r
'X' => array(9,9,6,6,6,9,9),
//'Y' => array(9,9,9,9,6,6,6),
'Y' => array(10,10,10,10,4,4,4),
'Z' => array(15,1,2,6,4,8,15),
// russian cp1251
'ƀ' => array(6,9,9,15,9,9,9),
'Ɓ' => array(14,8,8,14,9,9,14),
'Ƃ' => array(14,9,9,14,9,9,14),
'ƃ' => array(15,8,8,8,8,8,8),
'Ƅ' => array(14,9,9,9,9,9,14),
'ƅ' => array(15,8,8,14,8,8,15),
'ĀØ' => array(6,15,8,14,8,8,15),
//Ɔ is combine: >\n<
'Ƈ' => array(6,9,1,2,1,9,6),
'ƈ' => array(9,9,9,11,13,9,9),
'Ɖ' => array(13,9,9,11,13,9,9),
'Ɗ' => array(9,10,12,10,9,9,9),
'Ƌ' => array(7,9,9,9,9,9,9),
'ƌ' => array(8,13,10,8,8,8,8),// need to add \r
'ƍ' => array(9,9,9,15,9,9,9),
'Ǝ' => array(6,9,9,9,9,9,6),
'Ə' => array(15,9,9,9,9,9,9),
'Ɛ' => array(14,9,9,14,8,8,8),
'Ƒ' => array(6,9,8,8,8,9,6),
'ƒ' => array(14,4,4,4,4,4,4),
'Ɠ' => array(9,9,9,7,1,9,6),
'Ɣ' => array(2,7,10,10,7,2,2),// need to add Ā”
'ƕ' => array(9,9,6,6,6,9,9),
'Ɩ' => array(10,10,10,10,10,15,1),
'Ɨ' => array(9,9,9,7,1,1,1),
'Ƙ' => array(10,10,10,10,10,10,15),// \r
'ƙ' => array(10,10,10,10,10,15,0),// need to add \r
'ƚ' => array(12,4,4,6,5,5,6),
'ƛ' => array(8,8,8,14,9,9,14),// need to add |
'Ɯ' => array(8,8,8,14,9,9,14),
'Ɲ' => array(6,9,1,7,1,9,6),
'ƞ' => array(2,2,2,3,2,2,2),// need to add O
'Ɵ' => array(7,9,9,7,3,5,9)
),
 
$iSuperSampling = 3, $iMarg = 1, $iRad = 4;
function DigitalLED74($aRadius = 2, $aMargin= 0.6) {
$this->iRad = $aRadius;
$this->iMarg = $aMargin;
}
function SetSupersampling($aSuperSampling = 2) {
$this->iSuperSampling = $aSuperSampling;
}
 
function _GetLED($aLedIdx, $aColor = 0) {
$width= $this->iLED_X*$this->iRad*2 + ($this->iLED_X+1)*$this->iMarg + $this->iRad ;
$height= $this->iLED_Y*$this->iRad*2 + ($this->iLED_Y)*$this->iMarg + $this->iRad * 2;
 
// Adjust radious for supersampling
$rad = $this->iRad * $this->iSuperSampling;
 
// Margin in between "Led" dots
$marg = $this->iMarg * $this->iSuperSampling;
$swidth = $width*$this->iSuperSampling;
$sheight = $height*$this->iSuperSampling;
 
$simg = new RotImage($swidth, $sheight, 0, DEFAULT_GFORMAT, false);
$simg->SetColor($this->iColorSchema[$aColor][2]);
$simg->FilledRectangle(0, 0, $swidth-1, $sheight-1);
 
if(array_key_exists($aLedIdx, $this->iLEDSpec)) {
$d = $this->iLEDSpec[$aLedIdx];
}
else {
$d = array(0,0,0,0,0,0,0);
}
 
for($r = 0; $r < 7; ++$r) {
$dr = $d[$r];
for($c = 0; $c < 4; ++$c) {
if( ($dr & pow(2,3-$c)) !== 0 ) {
$color = $this->iColorSchema[$aColor][0];
}
else {
$color = $this->iColorSchema[$aColor][1];
}
 
$x = 2*$rad*$c+$rad + ($c+1)*$marg + $rad ;
$y = 2*$rad*$r+$rad + ($r+1)*$marg + $rad ;
 
$simg->SetColor($color);
$simg->FilledCircle($x,$y,$rad);
}
}
 
$img = new Image($width, $height, DEFAULT_GFORMAT, false);
$img->Copy($simg->img, 0, 0, 0, 0, $width, $height, $swidth, $sheight);
$simg->Destroy();
unset($simg);
return $img;
}
 
function StrokeNumber($aValStr, $aColor = 0) {
if($aColor < 0 || $aColor >= sizeof($this->iColorSchema))
$aColor = 0;
 
if(($n = strlen($aValStr)) == 0) {
$aValStr = ' ';
$n = 1;
}
 
for($i = 0; $i < $n; ++$i) {
$d = substr($aValStr, $i, 1);
if( $d >= '0' && $d <= '9' ) {
$d = (int)$d;
}
else {
$d = strtoupper($d);
}
$digit_img[$i] = $this->_GetLED($d, $aColor);
}
 
$w = imagesx($digit_img[0]->img);
$h = imagesy($digit_img[0]->img);
 
$number_img = new Image($w*$n, $h, DEFAULT_GFORMAT, false);
 
for($i = 0; $i < $n; ++$i) {
$number_img->Copy($digit_img[$i]->img, $i*$w, 0, 0, 0, $w, $h, $w, $h);
}
 
$number_img->Headers();
$number_img->Stream();
}
}
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb60x60.dat
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb60x60.dat
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_squares.inc.php
New file
0,0 → 1,150
<?php
//=======================================================================
// File: IMGDATA_SQUARES.INC
// Description: Base64 encoded images for squares
// Created: 2003-03-20
// Ver: $Id: imgdata_squares.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class ImgData_Squares extends ImgData {
var $name = 'Squares';
var $an = array(MARK_IMG_SQUARE =>'imgdata');
var $colors = array('bluegreen','blue','green',
'lightblue','orange','purple','red','yellow');
var $index = array('bluegreen' =>2,'blue'=>5,'green'=>6,
'lightblue'=>0,'orange'=>7,'purple'=>4,'red'=>3,'yellow'=>1);
var $maxidx = 7 ;
var $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' ;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_utils.inc.php
New file
0,0 → 1,523
<?php
/*=======================================================================
// File: JPGRAPH_UTILS.INC
// Description: Collection of non-essential "nice to have" utilities
// Created: 2005-11-20
// Ver: $Id: jpgraph_utils.inc.php 1089 2009-01-18 22:30:30Z ljp $
//
// 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::RaiseL(24001);//('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::RaiseL(24002);//('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'),
array('tm','2122'), /* Trademark symbol */
array('rtm','00AE') /* Registered trademark */
);
 
$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 DateScaleUtils
// Description: Help to create a manual date scale
//=============================================================================
DEFINE('DSUTILS_MONTH',1); // Major and minor ticks on a monthly basis
DEFINE('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis
DEFINE('DSUTILS_MONTH2',2); // Major ticks on a bi-monthly basis
DEFINE('DSUTILS_MONTH3',3); // Major icks on a tri-monthly basis
DEFINE('DSUTILS_MONTH6',4); // Major on a six-monthly basis
DEFINE('DSUTILS_WEEK1',5); // Major ticks on a weekly basis
DEFINE('DSUTILS_WEEK2',6); // Major ticks on a bi-weekly basis
DEFINE('DSUTILS_WEEK4',7); // Major ticks on a quod-weekly basis
DEFINE('DSUTILS_DAY1',8); // Major ticks on a daily basis
DEFINE('DSUTILS_DAY2',9); // Major ticks on a bi-daily basis
DEFINE('DSUTILS_DAY4',10); // Major ticks on a qoud-daily basis
DEFINE('DSUTILS_YEAR1',11); // Major ticks on a yearly basis
DEFINE('DSUTILS_YEAR2',12); // Major ticks on a bi-yearly basis
DEFINE('DSUTILS_YEAR5',13); // Major ticks on a five-yearly basis
 
 
class DateScaleUtils {
var $iMin=0, $iMax=0;
var $starthour,$startmonth, $startday, $startyear;
var $endmonth, $endyear, $endday;
var $tickPositions=array(),$minTickPositions=array();
var $iUseWeeks = true;
 
function UseWeekFormat($aFlg) {
$this->iUseWeeks = $aFlg;
}
 
function doYearly($aType,$aMinor=false) {
$i=0; $j=0;
$m = $this->startmonth;
$y = $this->startyear;
 
if( $this->startday == 1 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
}
++$m;
 
switch( $aType ) {
case DSUTILS_YEAR1:
for($y=$this->startyear; $y <= $this->endyear; ++$y ) {
if( $aMinor ) {
while( $m <= 12 ) {
if( !($y == $this->endyear && $m > $this->endmonth) ) {
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
}
++$m;
}
$m=1;
}
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
}
break;
case DSUTILS_YEAR2:
$y=$this->startyear;
while( $y <= $this->endyear ) {
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
for($k=0; $k < 1; ++$k ) {
++$y;
if( $aMinor ) {
$this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
}
}
++$y;
}
break;
case DSUTILS_YEAR5:
$y=$this->startyear;
while( $y <= $this->endyear ) {
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
for($k=0; $k < 4; ++$k ) {
++$y;
if( $aMinor ) {
$this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
}
}
++$y;
}
break;
}
}
 
function doDaily($aType,$aMinor=false) {
$m = $this->startmonth;
$y = $this->startyear;
$d = $this->startday;
$h = $this->starthour;
$i=0;$j=0;
 
if( $h == 0 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
}
$t = mktime(0,0,0,$m,$d,$y);
switch($aType) {
case DSUTILS_DAY1:
while( $t <= self::$iMax ) {
$t = strtotime('+1 day',$t);
$this->tickPositions[$i++] = $t;
if( $aMinor ) {
$this->minTickPositions[$j++] = strtotime('+12 hours',$t);
}
}
break;
case DSUTILS_DAY2:
while( $t <= $this->iMax ) {
$t = strtotime('+1 day',$t);
if( $aMinor ) {
$this->minTickPositions[$j++] = $t;
}
$t = strtotime('+1 day',$t);
$this->tickPositions[$i++] = $t;
}
break;
case DSUTILS_DAY4:
while( $t <= $this->iMax ) {
for($k=0; $k < 3; ++$k ) {
$t = strtotime('+1 day',$t);
if( $aMinor ) {
$this->minTickPositions[$j++] = $t;
}
}
$t = strtotime('+1 day',$t);
$this->tickPositions[$i++] = $t;
}
break;
}
}
 
function doWeekly($aType,$aMinor=false) {
$hpd = 3600*24;
$hpw = 3600*24*7;
// Find out week number of min date
$thursday = $this->iMin + $hpd * (3 - (date('w', $this->iMin) + 6) % 7);
$week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7;
$daynumber = date('w',$this->iMin);
if( $daynumber == 0 ) $daynumber = 7;
$m = $this->startmonth;
$y = $this->startyear;
$d = $this->startday;
$i=0;$j=0;
// The assumption is that the weeks start on Monday. If the first day
// is later in the week then the first week tick has to be on the following
// week.
if( $daynumber == 1 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
$t = mktime(0,0,0,$m,$d,$y) + $hpw;
}
else {
$t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber);
}
 
switch($aType) {
case DSUTILS_WEEK1:
$cnt=0;
break;
case DSUTILS_WEEK2:
$cnt=1;
break;
case DSUTILS_WEEK4:
$cnt=3;
break;
}
while( $t <= $this->iMax ) {
$this->tickPositions[$i++] = $t;
for($k=0; $k < $cnt; ++$k ) {
$t += $hpw;
if( $aMinor ) {
$this->minTickPositions[$j++] = $t;
}
}
$t += $hpw;
}
}
 
function doMonthly($aType,$aMinor=false) {
$monthcount=0;
$m = $this->startmonth;
$y = $this->startyear;
$i=0; $j=0;
 
// Skip the first month label if it is before the startdate
if( $this->startday == 1 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
$monthcount=1;
}
if( $aType == 1 ) {
if( $this->startday < 15 ) {
$this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
}
}
++$m;
 
// Loop through all the years included in the scale
for($y=$this->startyear; $y <= $this->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 == $this->endyear ? $this->endmonth : 12;
while( $m <= $stopmonth ) {
switch( $aType ) {
case DSUTILS_MONTH1:
// Set minor tick at the middle of the month
if( $aMinor ) {
if( $m <= $stopmonth ) {
if( !($y==$this->endyear && $m==$stopmonth && $this->endday < 15) )
$this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
}
}
// Major at month
// Get timestamp of first hour of first day in each month
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 
break;
case DSUTILS_MONTH2:
if( $aMinor ) {
// Set minor tick at start of each month
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
}
 
// Major at every second month
// Get timestamp of first hour of first day in each month
if( $monthcount % 2 == 0 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
}
break;
case DSUTILS_MONTH3:
if( $aMinor ) {
// Set minor tick at start of each month
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
}
// Major at every third month
// Get timestamp of first hour of first day in each month
if( $monthcount % 3 == 0 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
}
break;
case DSUTILS_MONTH6:
if( $aMinor ) {
// Set minor tick at start of each month
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
}
// Major at every third month
// Get timestamp of first hour of first day in each month
if( $monthcount % 6 == 0 ) {
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
}
break;
}
++$m;
++$monthcount;
}
$m=1;
}
 
// For the case where all dates are within the same month
// we want to make sure we have at least two ticks on the scale
// since the scale want work properly otherwise
if($this->startmonth == $this->endmonth && $this->startyear == $this->endyear && $aType==1 ) {
$this->tickPositions[$i++] = mktime(0 ,0 ,0, $this->startmonth + 1, 1, $this->startyear);
}
 
return array($this->tickPositions,$this->minTickPositions);
}
 
function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) {
$n = count($aData);
return $this->GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints);
}
 
function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) {
$diff = $aMax - $aMin;
$spd = 3600*24;
$spw = $spd*7;
$spm = $spd*30;
$spy = $spd*352;
 
if( $this->iUseWeeks )
$w = 'W';
else
$w = 'd M';
 
// Decision table for suitable scales
// First value: Main decision point
// Second value: Array of formatting depending on divisor for wanted max number of ticks. <divisor><formatting><format-string>,..
$tt = array(
array($spw, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',-1,DSUTILS_DAY4,'d M')),
array($spm, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
7,DSUTILS_WEEK1,$w,-1,DSUTILS_WEEK2,$w)),
array($spy, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
7,DSUTILS_WEEK1,$w,14,DSUTILS_WEEK2,$w,
30,DSUTILS_MONTH1,'M',60,DSUTILS_MONTH2,'M',-1,DSUTILS_MONTH3,'M')),
array(-1, array(30,DSUTILS_MONTH1,'M-Y',60,DSUTILS_MONTH2,'M-Y',90,DSUTILS_MONTH3,'M-Y',
180,DSUTILS_MONTH6,'M-Y',352,DSUTILS_YEAR1,'Y',704,DSUTILS_YEAR2,'Y',-1,DSUTILS_YEAR5,'Y')));
 
$ntt = count($tt);
$nd = floor($diff/$spd);
for($i=0; $i < $ntt; ++$i ) {
if( $diff <= $tt[$i][0] || $i==$ntt-1) {
$t = $tt[$i][1];
$n = count($t)/3;
for( $j=0; $j < $n; ++$j ) {
if( $nd/$t[3*$j] <= $aMaxTicks || $j==$n-1) {
$type = $t[3*$j+1];
$fs = $t[3*$j+2];
list($tickPositions,$minTickPositions) = $this->GetTicksFromMinMax($aMin,$aMax,$type,$aMinor);
return array($fs,$tickPositions,$minTickPositions,$type);
}
}
}
}
}
 
function GetTicksFromMinMax($aMin,$aMax,$aType,$aMinor=false,$aEndPoints=false) {
$this->starthour = date('G',$aMin);
$this->startmonth = date('n',$aMin);
$this->startday = date('j',$aMin);
$this->startyear = date('Y',$aMin);
$this->endmonth = date('n',$aMax);
$this->endyear = date('Y',$aMax);
$this->endday = date('j',$aMax);
$this->iMin = $aMin;
$this->iMax = $aMax;
 
if( $aType <= DSUTILS_MONTH6 ) {
$this->doMonthly($aType,$aMinor);
}
elseif( $aType <= DSUTILS_WEEK4 ) {
$this->doWeekly($aType,$aMinor);
}
elseif( $aType <= DSUTILS_DAY4 ) {
$this->doDaily($aType,$aMinor);
}
elseif( $aType <= DSUTILS_YEAR5 ) {
$this->doYearly($aType,$aMinor);
}
else {
JpGraphError::RaiseL(24003);
}
// put a label at the very left data pos
if( $aEndPoints ) {
$tickPositions[$i++] = $aData[0];
}
 
// put a label at the very right data pos
if( $aEndPoints ) {
$tickPositions[$i] = $aData[$n-1];
}
 
return array($this->tickPositions,$this->minTickPositions);
}
 
}
 
//=============================================================================
// Class ReadFileData
//=============================================================================
Class ReadFileData {
 
//----------------------------------------------------------------------------
// Desciption:
// Read numeric data from a file.
// Each value should be separated by either a new line or by a specified
// separator character (default is ',').
// Before returning the data each value is converted to a proper float
// value. The routine is robust in the sense that non numeric data in the
// file will be discarded.
//
// Returns:
// The number of data values read on success, FALSE on failure
//----------------------------------------------------------------------------
function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) {
$rh = fopen($aFile,'r');
if( $rh === false )
return false;
$tmp = array();
$lineofdata = fgetcsv($rh, 1000, ',');
while ( $lineofdata !== FALSE) {
$tmp = array_merge($tmp,$lineofdata);
$lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar);
}
fclose($rh);
 
// Now make sure that all data is numeric. By default
// all data is read as strings
$n = count($tmp);
$aData = array();
$cnt=0;
for($i=0; $i < $n; ++$i) {
if( $tmp[$i] !== "" ) {
$aData[$cnt++] = floatval($tmp[$i]);
}
}
return $cnt;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_canvtools.php
New file
0,0 → 1,515
<?php
/*=======================================================================
// File: JPGRAPH_CANVTOOLS.PHP
// Description: Some utilities for text and shape drawing on a canvas
// Created: 2002-08-23
// Ver: $Id: jpgraph_canvtools.php 782 2006-10-08 08:09:02Z 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 {
var $g;
var $w,$h;
var $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 {
var $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 {
var $ix,$iy,$iw,$ih,$ir=4;
var $iTxt,$iColor='black',$iFillColor='',$iFontColor='black';
var $iParaAlign='center';
var $iAutoBoxMargin=5;
var $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);
 
}
 
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_regstat.php
New file
0,0 → 1,202
<?php
/*=======================================================================
// File: JPGRAPH_REGSTAT.PHP
// Description: Regression and statistical analysis helper classes
// Created: 2002-12-01
// Ver: $Id: jpgraph_regstat.php 782 2006-10-08 08:09:02Z 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
 
var $xdata,$ydata; // Data vectors
var $y2; // 2:nd derivate of ydata
var $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/
*/
var $datax = array();
var $datay = array();
var $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
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb35x35.dat
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb35x35.dat
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_canvas.php
New file
0,0 → 1,94
<?php
/*=======================================================================
// File: JPGRAPH_CANVAS.PHP
// Description: Canvas drawing extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_canvas.php 782 2006-10-08 08:09:02Z 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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_antispam.php
New file
0,0 → 1,624
<?php
//=======================================================================
// File: JPGRAPH_ANTISPAM.PHP
// Description: Genarate anti-spam challenge
// Created: 2004-10-07
// Ver: $Id: jpgraph_antispam.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class HandDigits {
var $chars = array();
var $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 {
 
var $iData='';
var $iDD=null;
 
function AntiSpam($aData='') {
$this->iData = $aData;
$this->iDD = new HandDigits();
}
 
function Set($aData) {
$this->iData = $aData;
}
 
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($aStrokeFileName="") {
 
$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);
 
if( $aStrokeFileName!="" ) {
if( file_exists($aStrokeFileName) ) {
if( !@unlink($aStrokeFileName) )
return false;
}
imagejpeg($resimg,$aStrokeFileName);
return;
}
 
header("Content-type: image/jpeg");
$res=imagejpeg($resimg);
return $res;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_pie.php
New file
0,0 → 1,1437
<?php
/*=======================================================================
// File: JPGRAPH_PIE.PHP
// Description: Pie plot extension for JpGraph
// Created: 2001-02-14
// Ver: $Id: jpgraph_pie.php 1016 2008-07-03 21:15:39Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
 
 
// Defines for PiePlot::SetLabelType()
DEFINE("PIE_VALUE_ABS",1);
DEFINE("PIE_VALUE_PER",0);
DEFINE("PIE_VALUE_PERCENTAGE",0);
DEFINE("PIE_VALUE_ADJPERCENTAGE",2);
DEFINE("PIE_VALUE_ADJPER",2);
 
//===================================================
// CLASS PiePlot
// Description: Draws a pie plot
//===================================================
class PiePlot {
var $posx=0.5,$posy=0.5;
var $radius=0.3;
var $explode_radius=array(),$explode_all=false,$explode_r=20;
var $labels=null, $legends=null;
var $csimtargets=null; // Array of targets for CSIM
var $csimwintargets=null; // Array of window targets for CSIM
var $csimareas=''; // Generated CSIM text
var $csimalts=null; // ALT tags for corresponding target
var $data=null;
var $title;
var $startangle=0;
var $weight=1, $color="black";
var $legend_margin=6,$show_labels=true;
var $themearr = array(
"earth" => array(136,34,40,45,46,62,63,134,74,10,120,136,141,168,180,77,209,218,346,395,89,430),
"pastel" => array(27,415,128,59,66,79,105,110,42,147,152,230,236,240,331,337,405,38),
"water" => array(8,370,24,40,335,56,213,237,268,14,326,387,10,388),
"sand" => array(27,168,34,170,19,50,65,72,131,209,46,393));
var $theme="earth";
var $setslicecolors=array();
var $labeltype=0; // Default to percentage
var $pie_border=true,$pie_interior_border=true;
var $value;
var $ishadowcolor='',$ishadowdrop=4;
var $ilabelposadj=1;
var $legendcsimtargets = array();
var $legendcsimwintargets = array();
var $legendcsimalts = array();
var $adjusted_data = array();
var $guideline = null,$guidelinemargin=10;
var $iShowGuideLineForSingle = false;
var $iGuideLineCurve = false,$iGuideVFactor=1.4,$iGuideLineRFactor=0.8;
var $la = array(); // Holds the angle for each label
//---------------
// CONSTRUCTOR
function PiePlot($data) {
$this->data = array_reverse($data);
$this->title = new Text("");
$this->title->SetFont(FF_FONT1,FS_BOLD);
$this->value = new DisplayValue();
$this->value->Show();
$this->value->SetFormat('%.1f%%');
$this->guideline = new LineProperty();
}
 
//---------------
// PUBLIC METHODS
function SetCenter($x,$y=0.5) {
$this->posx = $x;
$this->posy = $y;
}
 
// Enable guideline and set drwaing policy
function SetGuideLines($aFlg=true,$aCurved=true,$aAlways=false) {
$this->guideline->Show($aFlg);
$this->iShowGuideLineForSingle = $aAlways;
$this->iGuideLineCurve = $aCurved;
}
 
// Adjuste the distance between labels and labels and pie
function SetGuideLinesAdjust($aVFactor,$aRFactor=0.8) {
$this->iGuideVFactor=$aVFactor;
$this->iGuideLineRFactor=$aRFactor;
}
 
function SetColor($aColor) {
$this->color = $aColor;
}
function SetSliceColors($aColors) {
$this->setslicecolors = $aColors;
}
function SetShadow($aColor='darkgray',$aDropWidth=4) {
$this->ishadowcolor = $aColor;
$this->ishadowdrop = $aDropWidth;
}
 
function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') {
$this->csimtargets=array_reverse($aTargets);
if( is_array($aWinTargets) )
$this->csimwintargets=array_reverse($aWinTargets);
if( is_array($aAlts) )
$this->csimalts=array_reverse($aAlts);
}
function GetCSIMareas() {
return $this->csimareas;
}
 
function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) {
 
//Slice number, ellipse centre (x,y), height, width, start angle, end angle
while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI;
while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI;
 
$sa = 2*M_PI - $sa;
$ea = 2*M_PI - $ea;
 
// Special case when we have only one slice since then both start and end
// angle will be == 0
if( abs($sa - $ea) < 0.0001 ) {
$sa=2*M_PI; $ea=0;
}
 
//add coordinates of the centre to the map
$xc = floor($xc);$yc=floor($yc);
$coords = "$xc, $yc";
 
//add coordinates of the first point on the arc to the map
$xp = floor(($radius*cos($ea))+$xc);
$yp = floor($yc-$radius*sin($ea));
$coords.= ", $xp, $yp";
//add coordinates every 0.2 radians
$a=$ea+0.2;
 
// If we cross the 260-limit with a slice we need to handle
// the fact that end angle is smaller than start
if( $sa < $ea ) {
while ($a <= 2*M_PI) {
$xp = floor($radius*cos($a)+$xc);
$yp = floor($yc-$radius*sin($a));
$coords.= ", $xp, $yp";
$a += 0.2;
}
$a -= 2*M_PI;
}
 
while ($a < $sa) {
$xp = floor($radius*cos($a)+$xc);
$yp = floor($yc-$radius*sin($a));
$coords.= ", $xp, $yp";
$a += 0.2;
}
//Add the last point on the arc
$xp = floor($radius*cos($sa)+$xc);
$yp = floor($yc-$radius*sin($sa));
$coords.= ", $xp, $yp";
if( !empty($this->csimtargets[$i]) ) {
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\"";
$tmp="";
if( !empty($this->csimwintargets[$i]) ) {
$this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
}
if( !empty($this->csimalts[$i]) ) {
$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\n";
}
}
 
function SetTheme($aTheme) {
if( in_array($aTheme,array_keys($this->themearr)) )
$this->theme = $aTheme;
else
JpGraphError::RaiseL(15001,$aTheme);//("PiePLot::SetTheme() Unknown theme: $aTheme");
}
function ExplodeSlice($e,$radius=20) {
if( ! is_integer($e) )
JpGraphError::RaiseL(15002);//('Argument to PiePlot::ExplodeSlice() must be an integer');
$this->explode_radius[$e]=$radius;
}
 
function ExplodeAll($radius=20) {
$this->explode_all=true;
$this->explode_r = $radius;
}
 
function Explode($aExplodeArr) {
if( !is_array($aExplodeArr) ) {
JpGraphError::RaiseL(15003);
//("Argument to PiePlot::Explode() must be an array with integer distances.");
}
$this->explode_radius = $aExplodeArr;
}
 
function SetStartAngle($aStart) {
if( $aStart < 0 || $aStart > 360 ) {
JpGraphError::RaiseL(15004);//('Slice start angle must be between 0 and 360 degrees.');
}
$this->startangle = 360-$aStart;
$this->startangle *= M_PI/180;
}
function SetFont($family,$style=FS_NORMAL,$size=10) {
JpGraphError::RaiseL(15005);//('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.');
}
// Size in percentage
function SetSize($aSize) {
if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) )
$this->radius = $aSize;
else
JpGraphError::RaiseL(15006);
//("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]");
}
function SetFontColor($aColor) {
JpGraphError::RaiseL(15007);
//('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.');
}
// Set label arrays
function SetLegends($aLegend) {
$this->legends = $aLegend;
}
 
// Set text labels for slices
function SetLabels($aLabels,$aLblPosAdj="auto") {
$this->labels = array_reverse($aLabels);
$this->ilabelposadj=$aLblPosAdj;
}
 
function SetLabelPos($aLblPosAdj) {
$this->ilabelposadj=$aLblPosAdj;
}
// Should we display actual value or percentage?
function SetLabelType($t) {
if( $t < 0 || $t > 2 )
JpGraphError::RaiseL(15008,$t);
//("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t).");
$this->labeltype=$t;
}
 
// Deprecated.
function SetValueType($aType) {
$this->SetLabelType($aType);
}
 
// Should the circle around a pie plot be displayed
function ShowBorder($exterior=true,$interior=true) {
$this->pie_border = $exterior;
$this->pie_interior_border = $interior;
}
// Setup the legends (Framework method)
function Legend(&$graph) {
$colors = array_keys($graph->img->rgb->rgb_table);
sort($colors);
$ta=$this->themearr[$this->theme];
$n = count($this->data);
 
if( $this->setslicecolors==null ) {
$numcolors=count($ta);
if( is_a($this,'PiePlot3D') ) {
$ta = array_reverse(array_slice($ta,0,$n));
}
}
else {
$this->setslicecolors = array_slice($this->setslicecolors,0,$n);
$numcolors=count($this->setslicecolors);
if( $graph->pieaa && !is_a($this,'PiePlot3D') ) {
$this->setslicecolors = array_reverse($this->setslicecolors);
}
}
$sum=0;
for($i=0; $i < $n; ++$i)
$sum += $this->data[$i];
 
// Bail out with error if the sum is 0
if( $sum==0 )
JpGraphError::RaiseL(15009);//("Illegal pie plot. Sum of all data is zero for Pie!");
 
// Make sure we don't plot more values than data points
// (in case the user added more legends than data points)
$n = min(count($this->legends),count($this->data));
if( $this->legends != "" ) {
$this->legends = array_reverse(array_slice($this->legends,0,$n));
}
for( $i=$n-1; $i >= 0; --$i ) {
$l = $this->legends[$i];
// Replace possible format with actual values
if( count($this->csimalts) > $i ) {
$fmt = $this->csimalts[$i];
}
else {
$fmt = "%d"; // Deafult Alt if no other has been specified
}
if( $this->labeltype==0 ) {
$l = sprintf($l,100*$this->data[$i]/$sum);
$alt = sprintf($fmt,$this->data[$i]);
}
elseif( $this->labeltype == 1) {
$l = sprintf($l,$this->data[$i]);
$alt = sprintf($fmt,$this->data[$i]);
}
else {
$l = sprintf($l,$this->adjusted_data[$i]);
$alt = sprintf($fmt,$this->adjusted_data[$i]);
}
 
if( empty($this->csimwintargets[$i]) ) {
$wintarg = '';
}
else {
$wintarg = $this->csimwintargets[$i];
}
 
if( $this->setslicecolors==null ) {
$graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0,$this->csimtargets[$i],$alt,$wintarg);
}
else {
$graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0,$this->csimtargets[$i],$alt,$wintarg);
}
}
}
// Adjust the rounded percetage value so that the sum of
// of the pie slices are always 100%
// Using the Hare/Niemeyer method
function AdjPercentage($aData,$aPrec=0) {
$mul=100;
if( $aPrec > 0 && $aPrec < 3 ) {
if( $aPrec == 1 )
$mul=1000;
else
$mul=10000;
}
$tmp = array();
$result = array();
$quote_sum=0;
$n = count($aData) ;
for( $i=0, $sum=0; $i < $n; ++$i )
$sum+=$aData[$i];
foreach($aData as $index => $value) {
$tmp_percentage=$value/$sum*$mul;
$result[$index]=floor($tmp_percentage);
$tmp[$index]=$tmp_percentage-$result[$index];
$quote_sum+=$result[$index];
}
if( $quote_sum == $mul) {
if( $mul > 100 ) {
$tmp = $mul / 100;
for( $i=0; $i < $n; ++$i ) {
$result[$i] /= $tmp ;
}
}
return $result;
}
arsort($tmp,SORT_NUMERIC);
reset($tmp);
for($i=0; $i < $mul-$quote_sum; $i++)
{
$result[key($tmp)]++;
next($tmp);
}
if( $mul > 100 ) {
$tmp = $mul / 100;
for( $i=0; $i < $n; ++$i ) {
$result[$i] /= $tmp ;
}
}
return $result;
}
 
 
function Stroke(&$img,$aaoption=0) {
// aaoption is used to handle antialias
// aaoption == 0 a normal pie
// aaoption == 1 just the body
// aaoption == 2 just the values
 
// Explode scaling. If anti anti alias we scale the image
// twice and we also need to scale the exploding distance
$expscale = $aaoption === 1 ? 2 : 1;
 
if( $this->labeltype == 2 ) {
// Adjust the data so that it will add up to 100%
$this->adjusted_data = $this->AdjPercentage($this->data);
}
 
$colors = array_keys($img->rgb->rgb_table);
sort($colors);
$ta=$this->themearr[$this->theme];
$n = count($this->data);
if( $this->setslicecolors==null ) {
$numcolors=count($ta);
}
else {
$this->setslicecolors = array_reverse(array_slice($this->setslicecolors,0,$n));
$numcolors=count($this->setslicecolors);
$tt = array_slice($this->setslicecolors,$n % $numcolors);
$tt2 = array_slice($this->setslicecolors,0,$n % $numcolors);
$tt2 = array_merge($tt, $tt2);
$this->setslicecolors = $tt + $tt2;
}
 
// Draw the slices
$sum=0;
for($i=0; $i < $n; ++$i)
$sum += $this->data[$i];
// Bail out with error if the sum is 0
if( $sum==0 )
JpGraphError::RaiseL(15009);//("Sum of all data is 0 for Pie.");
// Set up the pie-circle
if( $this->radius <= 1 )
$radius = floor($this->radius*min($img->width,$img->height));
else {
$radius = $aaoption === 1 ? $this->radius*2 : $this->radius;
}
 
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 ;
$n = count($this->data);
 
if( $this->explode_all )
for($i=0; $i < $n; ++$i)
$this->explode_radius[$i]=$this->explode_r;
 
// If we have a shadow and not just drawing the labels
if( $this->ishadowcolor != "" && $aaoption !== 2) {
$accsum=0;
$angle2 = $this->startangle;
$img->SetColor($this->ishadowcolor);
for($i=0; $sum > 0 && $i < $n; ++$i) {
$j = $n-$i-1;
$d = $this->data[$i];
$angle1 = $angle2;
$accsum += $d;
$angle2 = $this->startangle+2*M_PI*$accsum/$sum;
if( empty($this->explode_radius[$j]) )
$this->explode_radius[$j]=0;
 
if( $d < 0.00001 ) continue;
 
$la = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1);
 
$xcm = $xc + $this->explode_radius[$j]*cos($la)*$expscale;
$ycm = $yc - $this->explode_radius[$j]*sin($la)*$expscale;
$xcm += $this->ishadowdrop*$expscale;
$ycm += $this->ishadowdrop*$expscale;
 
$_sa = round($angle1*180/M_PI);
$_ea = round($angle2*180/M_PI);
 
// The CakeSlice method draws a full circle in case of start angle = end angle
// for pie slices we don't want this behaviour unless we only have one
// slice in the pie in case it is the wanted behaviour
if( $_ea-$_sa > 0.1 || $n==1 ) {
$img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,
$angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor);
}
}
}
 
//--------------------------------------------------------------------------------
// This is the main loop to draw each cake slice
//--------------------------------------------------------------------------------
 
// Set up the accumulated sum, start angle for first slice and border color
$accsum=0;
$angle2 = $this->startangle;
$img->SetColor($this->color);
 
// Loop though all the slices if there is a pie to draw (sum>0)
// There are n slices in total
for($i=0; $sum>0 && $i < $n; ++$i) {
 
// $j is the actual index used for the slice
$j = $n-$i-1;
 
// Make sure we havea valid distance to explode the slice
if( empty($this->explode_radius[$j]) )
$this->explode_radius[$j]=0;
 
// The actual numeric value for the slice
$d = $this->data[$i];
 
$angle1 = $angle2;
 
// Accumlate the sum
$accsum += $d;
 
// The new angle when we add the "size" of this slice
// angle1 is then the start and angle2 the end of this slice
$angle2 = $this->NormAngle($this->startangle+2*M_PI*$accsum/$sum);
 
// We avoid some trouble by not allowing end angle to be 0, in that case
// we translate to 360
 
 
// la is used to hold the label angle, which is centered on the slice
if( $angle2 < 0.0001 && $angle1 > 0.0001 ) {
$this->la[$i] = 2*M_PI - (abs(2*M_PI-$angle1)/2.0+$angle1);
}
elseif( $angle1 > $angle2 ) {
// The case where the slice crosses the 3 a'clock line
$this->la[$i] = 2*M_PI-$this->NormAngle($angle1 + ((2*M_PI - $angle1)+$angle2)/2);
}
else {
$this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1);
}
//$_sa = round($angle1*180/M_PI);
//$_ea = round($angle2*180/M_PI);
//$_la = round($this->la[$i]*180/M_PI);
//echo "ang1=$_sa , ang2=$_ea - la=$_la<br>";
 
// Too avoid rounding problems we skip the slice if it is too small
if( $d < 0.00001 ) continue;
 
// If the user has specified an array of colors for each slice then use
// that a color otherwise use the theme array (ta) of colors
if( $this->setslicecolors==null )
$slicecolor=$colors[$ta[$i%$numcolors]];
else
$slicecolor=$this->setslicecolors[$i%$numcolors];
// If we have enabled antialias then we don't draw any border so
// make the bordedr color the same as the slice color
if( $this->pie_interior_border && $aaoption===0 )
$img->SetColor($this->color);
else
$img->SetColor($slicecolor);
$arccolor = $this->pie_border && $aaoption===0 ? $this->color : "";
 
// Calculate the x,y coordinates for the base of this slice taking
// the exploded distance into account. Here we use the mid angle as the
// ray of extension and we have the mid angle handy as it is also the
// label angle
$xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale;
$ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale;
 
// If we are not just drawing the labels then draw this cake slice
if( $aaoption !== 2 ) {
 
$_sa = round($angle1*180/M_PI);
$_ea = round($angle2*180/M_PI);
$_la = round($this->la[$i]*180/M_PI);
//echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)<br>";
 
// The CakeSlice method draws a full circle in case of start angle = end angle
// for pie slices we don't want this behaviour unless we only have one
// slice in the pie in case it is the wanted behaviour
if( abs($_ea-$_sa) > 0.1 || $n==1 ) {
$img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,$_sa,$_ea,$slicecolor,$arccolor);
}
}
 
// If the CSIM is used then make sure we register a CSIM area for this slice as well
if( $this->csimtargets && $aaoption !== 1 ) {
$this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2);
}
}
 
// Format the titles for each slice
if( $aaoption!==2) {
for( $i=0; $i < $n; ++$i) {
if( $this->labeltype==0 ) {
if( $sum != 0 )
$l = 100.0*$this->data[$i]/$sum;
else
$l = 0.0;
}
elseif( $this->labeltype==1 ) {
$l = $this->data[$i]*1.0;
}
else {
$l = $this->adjusted_data[$i];
}
if( isset($this->labels[$i]) && is_string($this->labels[$i]) )
$this->labels[$i]=sprintf($this->labels[$i],$l);
else
$this->labels[$i]=$l;
}
}
 
If( $this->value->show && $aaoption !== 1 ) {
$this->StrokeAllLabels($img,$xc,$yc,$radius);
}
 
// Adjust title position
if( $aaoption !== 1 ) {
$this->title->Pos($xc,
$yc-$this->title->GetFontHeight($img)-$radius-$this->title->margin,
"center","bottom");
$this->title->Stroke($img);
}
 
}
 
//---------------
// PRIVATE METHODS
 
function NormAngle($a) {
while( $a < 0 ) $a += 2*M_PI;
while( $a > 2*M_PI ) $a -= 2*M_PI;
return $a;
}
 
function Quadrant($a) {
$a=$this->NormAngle($a);
if( $a > 0 && $a <= M_PI/2 )
return 0;
if( $a > M_PI/2 && $a <= M_PI )
return 1;
if( $a > M_PI && $a <= 1.5*M_PI )
return 2;
if( $a > 1.5*M_PI )
return 3;
}
 
function StrokeGuideLabels(&$img,$xc,$yc,$radius) {
$n = count($this->labels);
 
//-----------------------------------------------------------------------
// Step 1 of the algorithm is to construct a number of clusters
// a cluster is defined as all slices within the same quadrant (almost)
// that has an angular distance less than the treshold
//-----------------------------------------------------------------------
$tresh_hold=25 * M_PI/180; // 25 degrees difference to be in a cluster
$incluster=false; // flag if we are currently in a cluster or not
$clusters = array(); // array of clusters
$cidx=-1; // running cluster index
 
// Go through all the labels and construct a number of clusters
for($i=0; $i < $n-1; ++$i) {
// Calc the angle distance between two consecutive slices
$a1=$this->la[$i];
$a2=$this->la[$i+1];
$q1 = $this->Quadrant($a1);
$q2 = $this->Quadrant($a2);
$diff = abs($a1-$a2);
if( $diff < $tresh_hold ) {
if( $incluster ) {
$clusters[$cidx][1]++;
// Each cluster can only cover one quadrant
// Do we cross a quadrant ( and must break the cluster)
if( $q1 != $q2 ) {
// If we cross a quadrant boundary we normally start a
// new cluster. However we need to take the 12'a clock
// and 6'a clock positions into a special consideration.
// Case 1: WE go from q=1 to q=2 if the last slice on
// the cluster for q=1 is close to 12'a clock and the
// first slice in q=0 is small we extend the previous
// cluster
if( $q1 == 1 && $q2 == 0 && $a2 > (90-15)*M_PI/180 ) {
if( $i < $n-2 ) {
$a3 = $this->la[$i+2];
// If there isn't a cluster coming up with the next-next slice
// we extend the previous cluster to cover this slice as well
if( abs($a3-$a2) >= $tresh_hold ) {
$clusters[$cidx][1]++;
$i++;
}
}
}
elseif( $q1 == 3 && $q2 == 2 && $a2 > (270-15)*M_PI/180 ) {
if( $i < $n-2 ) {
$a3 = $this->la[$i+2];
// If there isn't a cluster coming up with the next-next slice
// we extend the previous cluster to cover this slice as well
if( abs($a3-$a2) >= $tresh_hold ) {
$clusters[$cidx][1]++;
$i++;
}
}
}
 
if( $q1==2 && $q2==1 && $a2 > (180-15)*M_PI/180 ) {
$clusters[$cidx][1]++;
$i++;
}
$incluster = false;
}
}
elseif( $q1 == $q2) {
$incluster = true;
// Now we have a special case for quadrant 0. If we previously
// have a cluster of one in quadrant 0 we just extend that
// cluster. If we don't do this then we risk that the label
// for the cluster of one will cross the guide-line
if( $q1 == 0 && $cidx > -1 &&
$clusters[$cidx][1] == 1 &&
$this->Quadrant($this->la[$clusters[$cidx][0]]) == 0 ) {
$clusters[$cidx][1]++;
}
else {
$cidx++;
$clusters[$cidx][0] = $i;
$clusters[$cidx][1] = 1;
}
}
else {
// Create a "cluster" of one since we are just crossing
// a quadrant
$cidx++;
$clusters[$cidx][0] = $i;
$clusters[$cidx][1] = 1;
}
}
else {
if( $incluster ) {
// Add the last slice
$clusters[$cidx][1]++;
$incluster = false;
}
else { // Create a "cluster" of one
$cidx++;
$clusters[$cidx][0] = $i;
$clusters[$cidx][1] = 1;
}
}
}
// Handle the very last slice
if( $incluster ) {
$clusters[$cidx][1]++;
}
else { // Create a "cluster" of one
$cidx++;
$clusters[$cidx][0] = $i;
$clusters[$cidx][1] = 1;
}
 
/*
if( true ) {
// Debug printout in labels
for( $i=0; $i <= $cidx; ++$i ) {
for( $j=0; $j < $clusters[$i][1]; ++$j ) {
$a = $this->la[$clusters[$i][0]+$j];
$aa = round($a*180/M_PI);
$q = $this->Quadrant($a);
$this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j";
}
}
}
*/
 
//-----------------------------------------------------------------------
// Step 2 of the algorithm is use the clusters and draw the labels
// and guidelines
//-----------------------------------------------------------------------
 
// We use the font height as the base factor for how far we need to
// spread the labels in the Y-direction.
$img->SetFont($this->value->ff,$this->value->fs,$this->value->fsize);
$fh = $img->GetFontHeight();
$origvstep=$fh*$this->iGuideVFactor;
$this->value->SetMargin(0);
 
// Number of clusters found
$nc = count($clusters);
 
// Walk through all the clusters
for($i=0; $i < $nc; ++$i) {
 
// Start angle and number of slices in this cluster
$csize = $clusters[$i][1];
$a = $this->la[$clusters[$i][0]];
$q = $this->Quadrant($a);
 
// Now set up the start and end conditions to make sure that
// in each cluster we walk through the all the slices starting with the slice
// closest to the equator. Since all slices are numbered clockwise from "3'a clock"
// we have different conditions depending on in which quadrant the slice lies within.
if( $q == 0 ) {
$start = $csize-1; $idx = $start; $step = -1; $vstep = -$origvstep;
}
elseif( $q == 1 ) {
$start = 0; $idx = $start; $step = 1; $vstep = -$origvstep;
}
elseif( $q == 2 ) {
$start = $csize-1; $idx = $start; $step = -1; $vstep = $origvstep;
}
elseif( $q == 3 ) {
$start = 0; $idx = $start; $step = 1; $vstep = $origvstep;
}
 
// Walk through all slices within this cluster
for($j=0; $j < $csize; ++$j) {
// Now adjust the position of the labels in each cluster starting
// with the slice that is closest to the equator of the pie
$a = $this->la[$clusters[$i][0]+$idx];
// Guide line start in the center of the arc of the slice
$r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)];
$x = round($r*cos($a)+$xc);
$y = round($yc-$r*sin($a));
// The distance from the arc depends on chosen font and the "R-Factor"
$r += $fh*$this->iGuideLineRFactor;
 
// Should the labels be placed curved along the pie or in straight columns
// outside the pie?
if( $this->iGuideLineCurve )
$xt=round($r*cos($a)+$xc);
 
// If this is the first slice in the cluster we need some first time
// proessing
if( $idx == $start ) {
if( ! $this->iGuideLineCurve )
$xt=round($r*cos($a)+$xc);
$yt=round($yc-$r*sin($a));
 
// Some special consideration in case this cluster starts
// in quadrant 1 or 3 very close to the "equator" (< 20 degrees)
// and the previous clusters last slice is within the tolerance.
// In that case we add a font height to this labels Y-position
// so it doesn't collide with
// the slice in the previous cluster
$prevcluster = ($i + ($nc-1) ) % $nc;
$previdx=$clusters[$prevcluster][0]+$clusters[$prevcluster][1]-1;
if( $q == 1 && $a > 160*M_PI/180 ) {
// Get the angle for the previous clusters last slice
$diff = abs($a-$this->la[$previdx]);
if( $diff < $tresh_hold ) {
$yt -= $fh;
}
}
elseif( $q == 3 && $a > 340*M_PI/180 ) {
// We need to subtract 360 to compare angle distance between
// q=0 and q=3
$diff = abs($a-$this->la[$previdx]-360*M_PI/180);
if( $diff < $tresh_hold ) {
$yt += $fh;
}
}
 
}
else {
// The step is at minimum $vstep but if the slices are relatively large
// we make sure that we add at least a step that corresponds to the vertical
// distance between the centers at the arc on the slice
$prev_a = $this->la[$clusters[$i][0]+($idx-$step)];
$dy = abs($radius*(sin($a)-sin($prev_a))*1.2);
if( $vstep > 0 )
$yt += max($vstep,$dy);
else
$yt += min($vstep,-$dy);
}
 
$label = $this->labels[$clusters[$i][0]+$idx];
 
if( $csize == 1 ) {
// A "meta" cluster with only one slice
$r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)];
$rr = $r+$img->GetFontHeight()/2;
$xt=round($rr*cos($a)+$xc);
$yt=round($yc-$rr*sin($a));
$this->StrokeLabel($label,$img,$xc,$yc,$a,$r);
if( $this->iShowGuideLineForSingle )
$this->guideline->Stroke($img,$x,$y,$xt,$yt);
}
else {
$this->guideline->Stroke($img,$x,$y,$xt,$yt);
if( $q==1 || $q==2 ) {
// Left side of Pie
$this->guideline->Stroke($img,$xt,$yt,$xt-$this->guidelinemargin,$yt);
$lbladj = -$this->guidelinemargin-5;
$this->value->halign = "right";
$this->value->valign = "center";
}
else {
// Right side of pie
$this->guideline->Stroke($img,$xt,$yt,$xt+$this->guidelinemargin,$yt);
$lbladj = $this->guidelinemargin+5;
$this->value->halign = "left";
$this->value->valign = "center";
}
$this->value->Stroke($img,$label,$xt+$lbladj,$yt);
}
 
// Udate idx to point to next slice in the cluster to process
$idx += $step;
}
}
}
 
function StrokeAllLabels(&$img,$xc,$yc,$radius) {
// First normalize all angles for labels
$n = count($this->la);
for($i=0; $i < $n; ++$i) {
$this->la[$i] = $this->NormAngle($this->la[$i]);
}
if( $this->guideline->iShow ) {
$this->StrokeGuideLabels($img,$xc,$yc,$radius);
}
else {
$n = count($this->labels);
for($i=0; $i < $n; ++$i) {
$this->StrokeLabel($this->labels[$i],$img,$xc,$yc,
$this->la[$i],
$radius + $this->explode_radius[$n-1-$i]);
}
}
}
 
// Position the labels of each slice
function StrokeLabel($label,&$img,$xc,$yc,$a,$radius) {
 
// Default value
if( $this->ilabelposadj === 'auto' )
$this->ilabelposadj = 0.65;
$r = $radius;
 
// We position the values diferently depending on if they are inside
// or outside the pie
if( $this->ilabelposadj < 1.0 ) {
 
$this->value->SetAlign('center','center');
$this->value->margin = 0;
$xt=round($this->ilabelposadj*$r*cos($a)+$xc);
$yt=round($yc-$this->ilabelposadj*$r*sin($a));
$this->value->Stroke($img,$label,$xt,$yt);
}
else {
 
$this->value->halign = "left";
$this->value->valign = "top";
$this->value->margin = 0;
// 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.
$img->SetFont($this->value->ff,$this->value->fs,$this->value->fsize);
$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);
if( $this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) {
$r *= $this->ilabelposadj;
}
$r += $img->GetFontHeight()/1.5;
 
$xt=round($r*cos($a)+$xc);
$yt=round($yc-$r*sin($a));
 
// Normalize angle
while( $a < 0 ) $a += 2*M_PI;
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;
$this->value->Stroke($img,$label,$xt-$dx*$w,$yt-$dy*$h);
}
}
} // Class
 
 
//===================================================
// CLASS PiePlotC
// Description: Same as a normal pie plot but with a
// filled circle in the center
//===================================================
class PiePlotC extends PiePlot {
var $imidsize=0.5; // Fraction of total width
var $imidcolor='white';
var $midtitle='';
var $middlecsimtarget='',$middlecsimwintarget='',$middlecsimalt='';
 
function PiePlotC($data,$aCenterTitle='') {
parent::PiePlot($data);
$this->midtitle = new Text();
$this->midtitle->ParagraphAlign('center');
}
 
function SetMid($aTitle,$aColor='white',$aSize=0.5) {
$this->midtitle->Set($aTitle);
 
$this->imidsize = $aSize ;
$this->imidcolor = $aColor ;
}
 
function SetMidTitle($aTitle) {
$this->midtitle->Set($aTitle);
}
 
function SetMidSize($aSize) {
$this->imidsize = $aSize ;
}
 
function SetMidColor($aColor) {
$this->imidcolor = $aColor ;
}
 
function SetMidCSIM($aTarget,$aAlt='',$aWinTarget='') {
$this->middlecsimtarget = $aTarget;
$this->middlecsimwintarget = $aWinTarget;
$this->middlecsimalt = $aAlt;
}
 
function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) {
 
//Slice number, ellipse centre (x,y), radius, start angle, end angle
while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI;
while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI;
 
$sa = 2*M_PI - $sa;
$ea = 2*M_PI - $ea;
 
// Special case when we have only one slice since then both start and end
// angle will be == 0
if( abs($sa - $ea) < 0.0001 ) {
$sa=2*M_PI; $ea=0;
}
 
// Add inner circle first point
$xp = floor(($this->imidsize*$radius*cos($ea))+$xc);
$yp = floor($yc-($this->imidsize*$radius*sin($ea)));
$coords = "$xp, $yp";
//add coordinates every 0.25 radians
$a=$ea+0.25;
 
// If we cross the 260-limit with a slice we need to handle
// the fact that end angle is smaller than start
if( $sa < $ea ) {
while ($a <= 2*M_PI) {
$xp = floor($radius*cos($a)+$xc);
$yp = floor($yc-$radius*sin($a));
$coords.= ", $xp, $yp";
$a += 0.25;
}
$a -= 2*M_PI;
}
 
while ($a < $sa) {
$xp = floor(($this->imidsize*$radius*cos($a)+$xc));
$yp = floor($yc-($this->imidsize*$radius*sin($a)));
$coords.= ", $xp, $yp";
$a += 0.25;
}
 
// Make sure we end at the last point
$xp = floor(($this->imidsize*$radius*cos($sa)+$xc));
$yp = floor($yc-($this->imidsize*$radius*sin($sa)));
$coords.= ", $xp, $yp";
 
// Straight line to outer circle
$xp = floor($radius*cos($sa)+$xc);
$yp = floor($yc-$radius*sin($sa));
$coords.= ", $xp, $yp";
 
//add coordinates every 0.25 radians
$a=$sa - 0.25;
while ($a > $ea) {
$xp = floor($radius*cos($a)+$xc);
$yp = floor($yc-$radius*sin($a));
$coords.= ", $xp, $yp";
$a -= 0.25;
}
//Add the last point on the arc
$xp = floor($radius*cos($ea)+$xc);
$yp = floor($yc-$radius*sin($ea));
$coords.= ", $xp, $yp";
 
// Close the arc
$xp = floor(($this->imidsize*$radius*cos($ea))+$xc);
$yp = floor($yc-($this->imidsize*$radius*sin($ea)));
$coords .= ", $xp, $yp";
 
if( !empty($this->csimtargets[$i]) ) {
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".
$this->csimtargets[$i]."\"";
if( !empty($this->csimwintargets[$i]) ) {
$this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
}
if( !empty($this->csimalts[$i]) ) {
$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\n";
}
}
 
 
function Stroke(&$img,$aaoption=0) {
 
// Stroke the pie but don't stroke values
$tmp = $this->value->show;
$this->value->show = false;
parent::Stroke($img,$aaoption);
$this->value->show = $tmp;
 
$xc = round($this->posx*$img->width);
$yc = round($this->posy*$img->height);
 
$radius = floor($this->radius * min($img->width,$img->height)) ;
 
 
if( $this->imidsize > 0 && $aaoption !== 2 ) {
 
if( $this->ishadowcolor != "" ) {
$img->SetColor($this->ishadowcolor);
$img->FilledCircle($xc+$this->ishadowdrop,$yc+$this->ishadowdrop,
round($radius*$this->imidsize));
}
 
$img->SetColor($this->imidcolor);
$img->FilledCircle($xc,$yc,round($radius*$this->imidsize));
 
if( $this->pie_border && $aaoption === 0 ) {
$img->SetColor($this->color);
$img->Circle($xc,$yc,round($radius*$this->imidsize));
}
 
if( !empty($this->middlecsimtarget) )
$this->AddMiddleCSIM($xc,$yc,round($radius*$this->imidsize));
 
}
 
if( $this->value->show && $aaoption !== 1) {
$this->StrokeAllLabels($img,$xc,$yc,$radius);
$this->midtitle->Pos($xc,$yc,'center','center');
$this->midtitle->Stroke($img);
}
 
}
 
function AddMiddleCSIM($xc,$yc,$r) {
$xc=round($xc);$yc=round($yc);$r=round($r);
$this->csimareas .= "<area shape=\"circle\" coords=\"$xc,$yc,$r\" href=\"".
$this->middlecsimtarget."\"";
if( !empty($this->middlecsimwintarget) ) {
$this->csimareas .= " target=\"".$this->middlecsimwintarget."\"";
}
if( !empty($this->middlecsimalt) ) {
$tmp = $this->middlecsimalt;
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\n";
}
 
function StrokeLabel($label,$img,$xc,$yc,$a,$r) {
 
if( $this->ilabelposadj === 'auto' )
$this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize;
 
parent::StrokeLabel($label,$img,$xc,$yc,$a,$r);
 
}
 
}
 
 
//===================================================
// CLASS PieGraph
// Description:
//===================================================
class PieGraph extends Graph {
var $posx, $posy, $radius;
var $legends=array();
var $plots=array();
var $pieaa = false ;
//---------------
// CONSTRUCTOR
function PieGraph($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->SetColor(array(255,255,255));
}
 
//---------------
// PUBLIC METHODS
function Add($aObj) {
 
if( is_array($aObj) && count($aObj) > 0 )
$cl = $aObj[0];
else
$cl = $aObj;
 
if( is_a($cl,'Text') )
$this->AddText($aObj);
elseif( is_a($cl,'IconPlot') )
$this->AddIcon($aObj);
else {
if( is_array($aObj) ) {
$n = count($aObj);
for($i=0; $i < $n; ++$i ) {
$this->plots[] = $aObj[$i];
}
}
else {
$this->plots[] = $aObj;
}
}
}
 
function SetAntiAliasing($aFlg=true) {
$this->pieaa = $aFlg;
}
function SetColor($c) {
$this->SetMarginColor($c);
}
 
function DisplayCSIMAreas() {
$csim="";
foreach($this->plots as $p ) {
$csim .= $p->GetCSIMareas();
}
//$csim.= $this->legend->GetCSIMareas();
if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) {
$this->img->SetColor($this->csimcolor);
$n = count($coords[0]);
for ($i=0; $i < $n; $i++) {
if ($coords[1][$i]=="poly") {
preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts);
$this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]);
$m = count($pts[0]);
for ($j=0; $j < $m; $j++) {
$this->img->LineTo($pts[1][$j],$pts[2][$j]);
}
} else if ($coords[1][$i]=="rect") {
$pts = preg_split('/,/', $coords[2][$i]);
$this->img->SetStartPoint($pts[0],$pts[1]);
$this->img->LineTo($pts[2],$pts[1]);
$this->img->LineTo($pts[2],$pts[3]);
$this->img->LineTo($pts[0],$pts[3]);
$this->img->LineTo($pts[0],$pts[1]);
}
}
}
}
 
// Method description
function Stroke($aStrokeFileName="") {
// 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;
$n = count($this->plots);
 
if( $this->pieaa ) {
 
if( !$_csim ) {
if( $this->background_image != "" ) {
$this->StrokeFrameBackground();
}
else {
$this->StrokeFrame();
}
}
 
 
$w = $this->img->width;
$h = $this->img->height;
$oldimg = $this->img->img;
 
$this->img->CreateImgCanvas(2*$w,2*$h);
$this->img->SetColor( $this->margin_color );
$this->img->FilledRectangle(0,0,2*$w-1,2*$h-1);
 
// Make all icons *2 i size since we will be scaling down the
// image to do the anti aliasing
$ni = count($this->iIcons);
for($i=0; $i < $ni; ++$i) {
$this->iIcons[$i]->iScale *= 2 ;
if( $this->iIcons[$i]->iX > 1 )
$this->iIcons[$i]->iX *= 2 ;
if( $this->iIcons[$i]->iY > 1 )
$this->iIcons[$i]->iY *= 2 ;
}
 
$this->StrokeIcons();
 
for($i=0; $i < $n; ++$i) {
if( $this->plots[$i]->posx > 1 )
$this->plots[$i]->posx *= 2 ;
if( $this->plots[$i]->posy > 1 )
$this->plots[$i]->posy *= 2 ;
 
$this->plots[$i]->Stroke($this->img,1);
 
if( $this->plots[$i]->posx > 1 )
$this->plots[$i]->posx /= 2 ;
if( $this->plots[$i]->posy > 1 )
$this->plots[$i]->posy /= 2 ;
}
$indent = $this->doframe ? ($this->frame_weight + ($this->doshadow ? $this->shadow_width : 0 )) : 0 ;
$indent += $this->framebevel ? $this->framebeveldepth + 1 : 0 ;
$this->img->CopyCanvasH($oldimg,$this->img->img,$indent,$indent,$indent,$indent,
$w-2*$indent,$h-2*$indent,2*($w-$indent),2*($h-$indent));
 
$this->img->img = $oldimg ;
$this->img->width = $w ;
$this->img->height = $h ;
 
for($i=0; $i < $n; ++$i) {
$this->plots[$i]->Stroke($this->img,2); // Stroke labels
$this->plots[$i]->Legend($this);
}
 
}
else {
// No antialias
if( !$_csim ) {
if( $this->background_image != "" ) {
$this->StrokeFrameBackground();
}
else {
$this->StrokeFrame();
$this->StrokeBackgroundGrad();
}
}
 
$this->StrokeIcons();
for($i=0; $i < $n; ++$i) {
$this->plots[$i]->Stroke($this->img);
$this->plots[$i]->Legend($this);
}
}
 
$this->legend->Stroke($this->img);
$this->footer->Stroke($this->img);
$this->StrokeTitles();
 
if( !$_csim ) {
 
// Stroke texts
if( $this->texts != null ) {
$n = count($this->texts);
for($i=0; $i < $n; ++$i ) {
$this->texts[$i]->Stroke($this->img);
}
}
 
if( _JPG_DEBUG ) {
$this->DisplayCSIMAreas();
}
 
// Should we do any final image transformation
if( $this->iImgTrans ) {
if( !class_exists('ImgTrans') ) {
require_once('jpgraph_imgtrans.php');
//JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.');
}
$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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_polar.php
New file
0,0 → 1,839
<?php
/*=======================================================================
// File: JPGRAPH_POLAR.PHP
// Description: Polar plot extension for JpGraph
// Created: 2003-02-02
// Ver: $Id: jpgraph_polar.php 868 2007-03-24 11:19:13Z 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 {
var $numpoints=0;
var $iColor='navy',$iFillColor='';
var $iLineWeight=1;
var $coord=null;
var $legendcsimtarget='';
var $legendcsimalt='';
var $legend="";
var $csimtargets=array(); // Array of targets for CSIM
var $csimareas=""; // Resultant CSIM area tags
var $csimalts=null; // ALT:s for corresponding target
var $line_style='solid',$mark;
 
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 {
var $angle_step=15,$angle_color='lightgray',$angle_label_color='black';
var $angle_fontfam=FF_FONT1,$angle_fontstyle=FS_NORMAL,$angle_fontsize=10;
var $angle_fontcolor = 'navy';
var $gridminor_color='lightgray',$gridmajor_color='lightgray';
var $show_minor_grid = false, $show_major_grid = true ;
var $show_angle_mark=true, $show_angle_grid=true, $show_angle_label=true;
var $angle_tick_len=3, $angle_tick_len2=3, $angle_tick_color='black';
var $show_angle_tick=true;
var $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) {
 
$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->Pos($this->img->width-$this->img->right_margin,$y,"right","top");
elseif( $this->title_adjust=="middle" || $this->title_adjust=="center" )
$this->title->Pos(($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->Pos($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 {
var $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 {
var $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 {
var $scale;
var $iType=POLAR_360;
var $axis;
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) {
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();
// 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);
}
}
}
}
 
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_stars.inc.php
New file
0,0 → 1,144
<?php
//=======================================================================
// File: IMGDATA_STARS.INC
// Description: Base64 encoded images for stars
// Created: 2003-03-20
// Ver: $Id: imgdata_stars.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
 
class ImgData_Stars extends ImgData {
var $name = 'Stars';
var $an = array(MARK_IMG_STAR => 'imgdata');
 
var $colors = array('bluegreen','lightblue','purple','blue','green','pink','red','yellow');
var $index = array('bluegreen'=>3,'lightblue'=>4,'purple'=>1,
'blue'=>5,'green'=>0,'pink'=>7,'red'=>2,'yellow'=>6);
var $maxidx = 7 ;
var $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==' ;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_balls.inc.php
New file
0,0 → 1,1063
<?php
//=======================================================================
// File: IMGDATA_ROUNDBALLS.INC
// Description: Base64 encoded images for small round markers
// Created: 2003-03-20
// Ver: $Id: imgdata_balls.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class ImgData_Balls extends ImgData {
var $name = 'Round Balls';
var $an = array(MARK_IMG_LBALL => 'imgdata_large',
MARK_IMG_MBALL => 'imgdata_small',
MARK_IMG_SBALL => 'imgdata_xsmall',
MARK_IMG_BALL => 'imgdata_xsmall');
var $colors_1 = array('blue','lightblue','brown','darkgreen',
'green','purple','red','gray','yellow','silver','gray');
var $index_1 = array('blue'=>9,'lightblue'=>1,'brown'=>6,'darkgreen'=>7,
'green'=>8,'purple'=>4,'red'=>0,'gray'=>5,'silver'=>3,'yellow'=>2);
var $maxidx_1 = 9 ;
 
var $colors_2 = array('blue','bluegreen','brown','cyan',
'darkgray','greengray','gray','green',
'greenblue','lightblue','lightred',
'purple','red','white','yellow');
var $index_2 = array('blue'=>9,'bluegreen'=>13,'brown'=>8,'cyan'=>12,
'darkgray'=>5,'greengray'=>6,'gray'=>2,'green'=>10,
'greenblue'=>3,'lightblue'=>1,'lightred'=>14,
'purple'=>7,'red'=>0,'white'=>11,'yellow'=>4);
var $maxidx_2 = 14 ;
 
 
var $colors_3 = array('bluegreen','cyan','darkgray','greengray',
'gray','graypurple','green','greenblue','lightblue',
'lightred','navy','orange','purple','red','yellow');
var $index_3 = array('bluegreen'=>1,'cyan'=>11,'darkgray'=>14,'greengray'=>10,
'gray'=>3,'graypurple'=>4,'green'=>9,'greenblue'=>7,
'lightblue'=>13,'lightred'=>0,'navy'=>2,'orange'=>12,
'purple'=>8,'red'=>5,'yellow'=>6);
var $maxidx_3 = 14 ;
 
var $colors,$index,$maxidx;
var $imgdata_large ;
var $imgdata_small ;
var $imgdata_xsmall ;
 
 
function GetImg($aMark,$aIdx) {
switch( $aMark ) {
case MARK_IMG_SBALL:
case MARK_IMG_BALL:
$this->colors = $this->colors_3;
$this->index = $this->index_3 ;
$this->maxidx = $this->maxidx_3 ;
break;
case MARK_IMG_MBALL:
$this->colors = $this->colors_2;
$this->index = $this->index_2 ;
$this->maxidx = $this->maxidx_2 ;
break;
default:
$this->colors = $this->colors_1;
$this->index = $this->index_1 ;
$this->maxidx = $this->maxidx_1 ;
break;
}
return parent::GetImg($aMark,$aIdx);
}
 
function ImgData_Balls() {
 
//==========================================================
// File: bl_red.png
//==========================================================
$this->imgdata_large[0][0]= 1072 ;
$this->imgdata_large[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAByF'.
'BMVEX/////////xsb/vb3/lIz/hIT/e3v/c3P/c2v/a2v/Y2P/'.
'UlL/Skr/SkL/Qjn/MTH/MSn/KSn/ISH/IRj/GBj/GBD/EBD/EA'.
'j/CAj/CAD/AAD3QkL3MTH3KSn3KSH3GBj3EBD3CAj3AAD1zMzv'.
'QkLvISHvIRjvGBjvEBDvEAjvAADnUlLnSkrnMTnnKSnnIRjnGB'.
'DnEBDnCAjnAADec3PeSkreISHeGBjeGBDeEAjWhITWa2vWUlLW'.
'SkrWISnWGBjWEBDWEAjWCAjWAADOnp7Oa2vOGCHOGBjOGBDOEB'.
'DOCAjOAADJrq7Gt7fGGBjGEBDGCAjGAADEpKS/v7+9QkK9GBC9'.
'EBC9CAi9AAC1e3u1a2u1Skq1KSm1EBC1CAi1AACtEBCtCBCtCA'.
'itAACngYGlCAilAACghIScOTmcCAicAACYgYGUGAiUCAiUAAiU'.
'AACMKSmMEACMAACEa2uEGAiEAAB7GBh7CAB7AABzOTlzGBBzCA'.
'BzAABrSkprOTlrGBhrAABjOTljAABaQkJaOTlaCABaAABSKSlS'.
'GBhSAABKKSlKGBhKAABCGBhCCABCAAA5CAA5AAAxCAAxAAApCA'.
'ApAAAhAAAYAACc9eRyAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'.
'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkRFD'.
'UHLytKAAAB4UlEQVR4nGNgIAK4mGjrmNq6BmFIWMmISUpKSmk5'.
'B8ZEokj4qoiLiQCBgqald3xaBpKMj6y4sLCQkJCIvIaFV0RaUR'.
'lCSk5cWEiAn19ASN7QwisuraihHiajKyEixM/NwckjoKrvEACU'.
'qumpg7pAUlREiJdNmZmLT9/cMzwps7Smc3I2WEpGUkxYkJuFiY'.
'lTxszePzY1v7Shc2oX2D+K4iLCgjzsrOw8embuYUmZeTVtPVOn'.
'gqSslYAOF+Ln4ZHWtXMPTcjMrWno7J82rRgoZWOsqaCgrqaqqm'.
'fn5peQmlsK1DR52vRaoFSIs5GRoYG5ub27n19CYm5pdVPnxKnT'.
'pjWDpLydnZwcHTz8QxMSEnJLgDL9U6dNnQ6Sio4PDAgICA+PTU'.
'zNzSkph8hADIxKS46Pj0tKTc3MLSksqWrtmQySAjuDIT8rKy0r'.
'Kz+vtLSmur6jb9JUIJgGdjxDQUVRUVFpaUVNQ1NrZ9+kKVOmTZ'.
'k6vR0sldJUAwQNTU2dnX0TgOJTQLrSIYFY2dPW1NbW2TNxwtQp'.
'U6ZMmjJt2rRGWNB3TO7vnzh5MsgSoB6gy7sREdY7bRrQEDAGOb'.
'wXOQW0TJsOEpwClmxBTTbZ7UDVIPkp7dkYaYqhuLa5trYYUxwL'.
'AADzm6uekAAcXAAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bl_bluegreen.png
//==========================================================
$this->imgdata_large[1][0]= 1368 ;
$this->imgdata_large[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMMFi8hE9b2uAAABOVJREFUeNq9lk2sJFUVx3+3qv'.
'tW95t57zFvhiFxmCFRUJRoNCQiJARMhiFx/Igxii5goTG6ZDAu'.
'/EhcSCIrTAgLEiKsJ8ywABNZEMJXEDYCukAmjgjzBkK/j35V1d'.
'333FtV97io97pfzwxfG86qcu/N+Z3zP+fcW/Apmfk4hx57+R/6'.
'Rqmc9ykhsWjlsUngAA1fXIQ7b73pI/186IGHnn9dH/8frC8v4I'.
'PiG53uaerR4GmKkv31mB8cyfjd946ZTwR66qVX9OTWIi8UKUv9'.
'BOrZXpYZvFeiBvzI0fgSUSFKwbVG+Pl1V3HH0VvNR4KeeukV/f'.
'PmMmdHhst76aXD64AbeVQ9bjNHaiGOC2o3wLrAb2/4LL/84ffn'.
'fCdzkOdayKpLppBemrBsU5Y1Zdmm9LJdGU6E/t4M24Q26jRDRL'.
'j3mdc49cSTekFsMzs5XuTsyLDUNSDQ25NwKOly9YIl22MYhJr/'.
'uoDtBBoT0CxBRGYOAhibIaOCe//2MpfM6KHnX9cXipSlbkKWmS'.
'nk9iv38J0jixw7vJfrTMYBOvhSoQHJBS09ANELloAGDxW8tfoW'.
'J+5/UC8CPS0LU7r3SpYarr7M8rmFjMPLXT6/33L4si7Z2GCrQC'.
'+0ctlOaNs9DReV8vSLr85ndPLpZ/WNvHW+01kAVFBOGvJx0wYg'.
'Sp47RIQ4Emwa8FGJXlDxSCFo5YlVgAo2hwPue/hRndboTV3EW2'.
'Wp3k6wBp8q56QiWzecW6vwQfnPRkAWhFgILnq08jQ+R2nlUzzN'.
'uES9Q7Vd+9fba7NmWJW61db2247qACmcjxXr45psYphsFGSLBu'.
'kIajxqtjNwHkvAjQt0sg3crhPA2+fPz0CuyNFOghsGsr19mnFg'.
'DGwrRm8UoAtNmQPQtRXDgdC4HImCFEKcCE0oieUWUYq2LtbiGp'.
'mBQmppfIkjw45DK0QNNkvQ0jMBtPL0UnDRM1rN+cxKwzvOo2NP'.
'tykR9a1kfpZNDLMG6QDYJqCTBvUe1+uxs+YKyPoGrTwY2HhvC4'.
'CDWQd5d4xNApNQEEMgjgLdUCLBQ5cprL/trwNwKG2IUmDqDFd5'.
'sr5BWrlxuSdLDFEFlqAzXGc4zFjupqh6uqYihpxJcEgp026l2w'.
'7wFUv7Z6AvrfRo/n0OYzPwIKE3HUKAJg2otMBiElnsF7wngis9'.
'3ZDjNnLi7huCWUZfueZKTu/M0V3HvmkOFDVxVKDG04ScejSgW5'.
'V0q5JYFEghuDLHlTmToqDeGOCKIVtrW9hsdmXufEcNLPSXuPHa'.
'a+bvuh9df5AH/v5PDFmbWQC3Mx+TVvfGVTRB2CodNgT2JBX003'.
'aANZAYS/BxCv32TV/l2C03G7jgmfjGiT/qmeEmibEYm7XzAO2k'.
'A+pbgHhBgydqu54YO5eRiLCy7yDvPP6Xqf+5Z+Lu277OYuOpiw'.
'H15oBmlNOMcmK5RbP+PrEscGU+DSAxdg4CICIkxnLP8aNz63Og'.
'H3/rdvOb795GVhuaYo0oBc3GGrEsUPVTwO6a7LYd+X51x3Hu/t'.
'lP5tS65FN+6okn9U+n/sqb596dTvhOF+02myXTmkQNrOw7yD3H'.
'j14E+UDQjp24/0E9/eKrbA4HH3aMK1b2ccvXvswjv//1J/s5ud'.
'Due/hRPfP+OmfOrk7vrn7a48ihA3zh8CH+8Iuffiw/n4r9H1ZZ'.
'0zz7G56hAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bl_yellow.png
//==========================================================
$this->imgdata_large[2][0]= 1101 ;
$this->imgdata_large[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAB2l'.
'BMVEX//////////+///+f//9b//8b//73//7X//63//6X//5T/'.
'/4z//4T//3P//2v//1r//0r//0L//zH//yn//yH//xj//xD//w'.
'j//wD/90L/9zn/9zH/9xj/9xD/9wj/9wD39yn37zn37zH37yH3'.
'7xD37wj37wDv70Lv50rv50Lv5znv5yHv5xjv5wjv5wDn51Ln5x'.
'Dn3jHn3iHn3hjn3hDn3gje3oze3nPe3lLe1oze1nPe1lLe1ine'.
'1iHe1hje1hDe1gje1gDW1qXW1mvWzqXWzkLWzhjWzhDWzgjWzg'.
'DOzrXOzq3OzpzOzgDOxkrOxinOxhjOxhDOxgjOxgDGxqXGxnvG'.
'xmvGvRjGvRDGvQjGvQDFxbnAvr6/v7+9vaW9vZS9vQi9vQC9tR'.
'C9tQi9tQC7u7W1tZS1tXu1tTG1tQi1rRC1rQi1rQCtrYytrSGt'.
'rQitrQCtpYStpSGtpQitpQClpYSlpXulpQClnBClnAilnACcnG'.
'ucnAicnACclAiclACUlFqUlCmUlAiUlACUjFKUjAiUjACMjFKM'.
'jEqMjACMhACEhACEewB7ezF7exB7ewB7cwBzcylzcwBzaxBzaw'.
'BraxhrawhrawBrYxBrYwBjYwBjWgBaWgBaUgCXBwRMAAAAAXRS'.
'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'.
'LdfvwAAAAHdElNRQfTAwkRFBKiJZ4hAAAB7ElEQVR4nI3S+1vS'.
'UBgHcB67WJmIMWAVdDHEDLBC6Go0slj3Ft0m9RRBWQEmFZFDEM'.
'Qgt0EMFBY7p/+198hj1kM/9N1+++x73rOd6XT/kStnTx4fPzd9'.
'uwfOjFhomj7smAhwj/6Cm2O0xUwy6g7cCL99uCW3jtBmE7lsdr'.
'fvejgpzP7uEDFRRoqy2k8xQPnypo2BUMP6waF9Vpf3ciiSzErL'.
'XTkPc0zDe3bsHDAcc00yoVgqL3UWN2iENpspff+2vn6D0+NnZ9'.
'6lC5K6RuSqBTZn1O/a3rd7v/MSez+WyIpVFX8GuuCA9SjD4N6B'.
'oRNTfo5PCAVR0fBXoIuOQzab1XjwwNHx00GOj8/nKtV1DdeArk'.
'24R+0ul9PjmbrHPYl+EipyU0OoQSjg8/m83kl/MMhx0fjCkqio'.
'SMOE7t4JMAzDsizH81AqSdW2hroLPg4/CEF4PhKNx98vlevrbY'.
'QQXgV6kXwVfjkTiSXmhYVcSa7DIE1DOENe7GM6lUym0l+EXKks'.
'K20VAeH2M0JvVgrZfL5Qqkiy0lRVaMBd7H7EZUmsiJJcrTdVja'.
'wGpdbTLj3/3qwrUOjAfGgg4LnNA5tdQx14Hm00QFBm65hfNzAm'.
'+yIFhFtzuj+z2MI/MQn6Uez5pz4Ua41G7VumB/6RX4zMr1TKBr'.
'SXAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bl_silver.png
//==========================================================
$this->imgdata_large[3][0]= 1481 ;
$this->imgdata_large[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAADAF'.
'BMVEUAAADOzs7Gxsa9vb21tbXOxsbOzsbGzsb3///O1ta1vb2c'.
'paVSWlpKWlpSY2ve5+97hIze7/9aY2vO5/9zhJRaa3tSY3PGzt'.
'aMlJxrc3tja3NKUlpCSlK1vcZze4RSWmPW5/+Upb3G3v9zhJxS'.
'Y3t7jKVaa4TO3veltc6ElK1re5Rjc4ycpbV7hJRaY3M5QlLn7/'.
'/Gzt6lrb2EjJzO3v9ja3vG1ve9zu+1xueltdacrc6UpcaMnL1C'.
'SlqElLV7jK1zhKVre5zW3u/O1ue1vc6ttcaMlKVze4xrc4RSWm'.
'tKUmPG1v+9zve1xu+tveeltd6crdbe5/+9xt6cpb17hJxaY3s5'.
'QlrW3vfO1u/Gzue1vdattc6lrcaUnLWMlK2EjKVze5Rrc4xja4'.
'RSWnNKUmtCSmO9xuecpcZ7hKVaY4TW3v/O1vfGzu+1vd6ttdal'.
'rc69xu+UnL2MlLWEjK1ze5xrc5R7hK1ja4zO1v+1veettd6lrd'.
'aMlL3Gzv/39//W1t7Gxs61tb29vcatrbWlpa2cnKWUlJyEhIx7'.
'e4TW1ufGxta1tcZSUlqcnK3W1u+UlKW9vda1tc57e4ytrcalpb'.
'1ra3vOzu9jY3OUlK29vd6MjKWEhJxaWmtSUmNzc4xKSlpjY3tK'.
'SmNCQlqUjJzOxs7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
'AAAAAAAAAAAAAAAAAAAAAAAAD///9fnkWVAAAAAnRSTlP/AOW3'.
'MEoAAAABYktHRP+lB/LFAAAACXBIWXMAAABFAAAARQBP+QatAA'.
'AB/klEQVR42mNgxAsYqCdd3+lcb4hLmj8wMMvEu8DCMqYbU9op'.
'UEFB2MTb26eyysomFl06XEEhUCHLpAKo2z/fujikEUVaXUFBMB'.
'BouLePuV+VVWGRciIXknSEsImCQd3//xwmPr65llaFcSFJHkjS'.
'3iYmWUDZ//8NfCr989NjNUMSUyTg0jneSiaCINn/gmlVQM12qg'.
'lJnp5waTMTE5NAkCyHWZW/lXWNfUlikmdYK0zax7siS4EDKJtd'.
'mQeU1XRwLBdLkRGASucWmGVnZ4dnhZvn5lmm29iVOWpnJqcuko'.
'JKR1Wm5eTkRKYF5eblp9sU2ZeUJiV7zbfVg0pH56UFBQXNjIqK'.
'jgkujItX1koKTVmYajsdKu2qETVhwgSXiUDZ2Bn9xqUeoZ5e0t'.
'LzYYZ3B092ndjtOnmKTmycW1s7SHa+l5dtB8zlccE6RlN0dGbM'.
'mDVbd5KupNBcL6+F82XgHouLj5vRP2PWLGNdd4+ppnxe8tJec6'.
'XnNsKkm0uVQ5RDRHQTPTym68nPlZbvkfYCexsa5rpJ2qXa5Umm'.
'ocmec3m8vHjmSs+fgxyhC5JDQ8WSPT2lvbzm8vDIe0nbtiBLN8'.
'8BigNdu1B6Lsje+fPbUFMLi5TMfGmvHi/puUAv23q2YCTFNqH5'.
'MvPnSwPh3HasCbm3XUpv+nS5VtrkEkwAANSTpGHdye9PAAAASn'.
'RFWHRzaWduYXR1cmUANGJkODkyYmE4MWZhNTk4MTIyNDJjNjUx'.
'NzZhY2UxMDAzOGFhZjdhZWIyNzliNTM2ZGFmZDlkM2RiNDU3Zm'.
'NlNT9CliMAAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bl_purple.png
//==========================================================
$this->imgdata_large[4][0]= 1149 ;
$this->imgdata_large[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAACAV'.
'BMVEX/////////7///5///1v//xv//rf//pf//lP//jP//hP//'.
'c///a///Wv//Wvf/Uv//Sv//Qv//Qvf/Off/Mf//Kf//If//If'.
'f/GP//GPf/EP//EPf/CP//CPf/CO//AP//APf3Oe/3Kff3Ke/3'.
'Ie/3GO/3EO/3AO/vSu/vSufvOefvMefvIefvGOfvEOfvCOfvAO'.
'fnUufnSufnMd7nId7nGN7nGNbnEN7nCN7nAN7ejN7ejNbec97e'.
'c9beUtbeQtbeIdbeGNbeENbeCNbeANbWpdbWa9bWQs7WGM7WEM'.
'7WCM7WAM7Otc7Orc7OnM7OSsbOIb3OGMbOEMbOCMbOAM7OAMbG'.
'pcbGnMbGe8bGa8bGKbXGEL3GCL3GAL3FucXBu73AvsC/v7+9pb'.
'29Ka29GLW9ELW9CLW9AL29ALW5rrm1lLW1e7W1MbW1GKW1EK21'.
'CLW1CK21AK2tjK2thKWtMaWtIaWtGJytCK2tCKWtAK2tAKWlhK'.
'Wle6WlEJylCJylAKWlAJyca5ycGJScEJScCJScAJycAJSUWpSU'.
'UoyUKZSUEIyUCIyUAJSUAIyMUoyMSoyMIYSMEISMCISMAIyMAI'.
'SECHuEAISEAHt7MXt7EHt7CHt7AHt7AHNzKXNzEGtzAHNzAGtr'.
'GGtrEGNrCGtrAGtrAGNjCFpjAGNjAFpaAFpaAFIpZn4bAAAAAX'.
'RSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsS'.
'AdLdfvwAAAAHdElNRQfTAwkRFB0ymoOwAAAB9UlEQVR4nGNgIA'.
'K42hhqGtm5+WFIWClKycvLK6gbuARGoEj4aMjLSElISUir6Tt7'.
'x+aEIWR8leQlwEBSTc/CK7awLguuR0lGQkJMVFRUTFJVzwko1d'.
'oFk9OQl5IQE+Dh5hVR0TV3CkkvbJgyASJjDZIR5GBl5eRX0TH1'.
'DEqrbJ2ypBEspSgvJSXKw8bMxMavbOLoGZNf1TZlybw4oIyfLN'.
'BxotxsLEzsQiaOHkFpBQ2905esrAZK2SpIAaUEuDm5+LTNPAKj'.
'C+pbps1evrIDKGWnLictKSkuLKyoZQyUya9o7Z2+YMXKGUApew'.
'M9PTVdXR0TEwf3wOjUirruafOXL18xFyjl72Kpb25qaurg4REU'.
'EFVe2zJ5zpLlK1aCpbydnZ2dnDwDA6NTopLLeiZNXbB8BcTAyP'.
'TQ0JDg4KCY1NS83JKmiVOBepYvX9UPlAovzEiPSU/LLyior2vq'.
'mjZr3vLlIF01IC+XVhUWFlZW1Lc290ycOGfxohVATSsXx4Oksn'.
'vaWlsb2tq6J0+bM2/RohVA81asbIcEYueU3t7JU6ZNnwNyGkhm'.
'+cp5CRCppJnzZ8+ZM3/JUogECBbBIixr8Yqly8FCy8F6ltUgoj'.
'lz7sqVK2ByK+cVMSCDxoUrwWDVysXt8WhJKqG4Y8bcuTP6qrGk'.
'QwwAABiMu7T4HMi4AAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bl_gray.png
//==========================================================
$this->imgdata_large[5][0]= 905 ;
$this->imgdata_large[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAABO1'.
'BMVEX////////3///39/fv7+/e5+fW3t7Wzs7WxsbG1tbGzsbG'.
'xsbDxMS/v7++wMC+v7+9zsa9xsa9vb29tbW9ra29pa24uLi1xs'.
'a1vb21tbWxtrattbWmpqalra2cra2cpaWcnJycjIyUpaWUnJyU'.
'lJSUjIyMnJyMnJSMlJSMlIyMjJSMjIyElJSElIyEjIyEhIR7jI'.
'x7hIR7hHt7e3t7e3N7e2tzhIRze3tze3Nzc3Nre3trc3Nrc2tr'.
'a2tjc3Njc2tja3Nja2tjY2NjWlpaa2taY2taY2NaY1paWlpaUl'.
'JSY2NSY1pSWlpSWlJSUlJSUkpKWlpKWlJKUlpKUlJKUkpKSkpK'.
'SkJCUlJCUkJCSkpCSkJCQkI5Sko5QkI5Qjk5OUI5OTkxQkIxOT'.
'kxMTkxMTEpMTEhMTEhKSkYISEpy7AFAAAAAXRSTlMAQObYZgAA'.
'AAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdE'.
'lNRQfTAwkRFQfW40uLAAABx0lEQVR4nI3SbXfSMBQA4NV3nce5'.
'TecAHUywRMHSgFuBCFsQUqwBS1OsWQh0GTj//y8wZUzdwQ/efM'.
'tzcm/uuXdj4z9ic/PR9k4qk1qDnf0X2/uZzKt8GaRvSubg4LVp'.
'mkWzCGAT/i3Zsm2XNQHLsm2n2937LaaNnGoJFAEo27B50qN0ay'.
'Wg26lXsw8fP8nmzcJb2CbsnF5JmmCE8ncN404KvLfsYwd7/MdV'.
'Pdgl/VbKMIzbuwVgVZw2JlSKJTVJ3609vWUY957lgAUd1KNcqr'.
'yWnOcOPn8q7d5/8PywAqsOOiVDrn42NFk+HQ7dVuXNYeFdBTpN'.
'nY5JdZl8xI5Y+HXYaTVqEDp1hAnRohZM03EUjMdhn5wghOoNnD'.
'wSK7KiiDPqEtz+iD4ctdyAifNYzUnScBSxwPd6GLfRURW7Ay5i'.
'pS5bmrY8348C5vvUI+TLiIVSJrVA0heK/GDkJxYMRoyfCSmk4s'.
'uWc3yic/oBo4yF374LGQs5Xw0GyQljI8bYmEsxVUoKxa6HMpAT'.
'vgyhU2mR8uU1pXmsa8ezqb6U4mwWF/5MeY8uLtQ0nmmQ8UWYvb'.
'EcJaYWar7QhztrO5Wr4Q4hDbAG/4hfTAF2iCiWrCEAAAAASUVO'.
'RK5CYII=' ;
 
//==========================================================
// File: bl_brown.png
//==========================================================
$this->imgdata_large[6][0]= 1053 ;
$this->imgdata_large[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABoV'.
'BMVEX////Gzs7GvbXGrZTGpXu9nHO1nHO1nIy9taXGxs7GtaXO'.
'nHPGlFrGjEq9hEq1hEqte0Klczmcazmce1KtnIzGxsbGvb3OlF'.
'LOlFq9hFKte0qcc0KUYzGEWimMc1K9ta3OnGvOnGPWnGO9jFq9'.
'jFKlc0KUazmMYzl7UilzUjGtpZzGxr3GnGPWpWvepXO1hFJ7Wj'.
'FrSiFjUjG1ra3GnHPvxpT/5733zpythFKUa0KEYzlzUilaOSF7'.
'Wjm9jErvvYz/99b///f/78bnrYS1hFqle0p7UjFrSiljQiFCMR'.
'iMhHO9lGvGjFLWnGv/3q3////erXuthEqlc0paQiFKMRhSQin/'.
'1qX/997//++cc0pjSilaQilKORhCKRiclIy9pYzGlGPntYT33q'.
'3vvZSEWjlSOSE5KRB7c2O1lHutczmthFqte1JrWkqtjGtCKRBa'.
'SjmljGuca0KMYzGMaznOztaclISUYzmEWjFKOSF7a1qEYzFaSi'.
'GUjISEa0pKOSm9vb2llIxaQhg5IQiEc2tzY0paORilnJy1raVS'.
'OSljUkJjWkKTpvQWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'.
'gAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkREiei'.
'zP2EAAAB9UlEQVR4nGWS/VfSUBjHL5QluhhBxtwyWcCus5Blpm'.
'wDC4ONaWXCyBi7RMZmpQ2Bypm9W/byV3cHHo/W88s95/s5z/d5'.
'uwCcCh/4L3zAf+bs0NC588On9QAYGSUuBINk6GI4cmnsBLk8Go'.
'1SFEGMkzRzZeLq5JE8FvDHouw1lqXiCZJOcnCKnx4AcP0GBqmZ'.
'mRgRT9MMB4Wbs7cGSXNRik3dnp9fiMUzNCNKgpzN9bsaWaQo9s'.
'7dfH7pXiFTZCBU1JK27LmtBO8TDx7mV1eXHqXXyiIUFLWiVzHx'.
'BxcJIvV4/cn6wkqmWOOwmVE3UQOAp6HxRKL5bGPj+VwhUhalFq'.
'8alm5vAt+LlySZTsebzcKrraIIW4JqZC3N3ga+1+EQTZKZta1M'.
'pCZCSeDViqVrThsEdsLJZLJYLpZrHVGScrKBvTQNtQHY6XIM02'.
'E6Ik7odRW1Dzy3N28n3kGuB3tQagm7UMBFXI/sATAs7L5vdbEs'.
'8Lycm923NB0j5wMe6KOsKIIyxcuqauxbrmlqyEWfPmPy5assY1'.
'U1SvWKZWom9nK/HfQ3+v2HYZSMStayTNN0PYKqg11P1nWsWq7u'.
'4gJeY8g9PLrddNXRdW8Iryv86I3ja/9s26gvukhDdvUQnIjlKr'.
'IdZCNH+3Xw779qbG63f//ZOzb6C4+ofdbzERrSAAAAAElFTkSu'.
'QmCC' ;
 
//==========================================================
// File: bl_darkgreen.png
//==========================================================
$this->imgdata_large[7][0]= 1113 ;
$this->imgdata_large[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAB2l'.
'BMVEX////////3///v///n/+/e99bW/+/W99bO786/v7++vr69'.
'/96999a7wb24vbu1/9a1zqW1u7itxrWosq6l772l1qWlxrWlxq'.
'2lva2cxpSU562U3q2UxqWUvaWUpZyM77WM57WMvYyMtZyMrZyM'.
'pZSMnJSEvZyEtYyErZSElIx7zpR7xpx7xpR7vZR7jIRz1pRzxp'.
'RzjIRrzpRrzoxrxoxrtYRrrYxrrXtrpYRrhHNjzoxjxoxjxoRj'.
'vYRjtYRjrXtjpXtjlGNje2tazoxazoRaxoxaxoRavYRatYRatX'.
'tarXtapXNanHNajFpae2tSzoRSxoRSvXtStXtSrXtSrXNSpXNS'.
'nHNSnGtSlGtSlGNSjGtSjGNKvXtKtXNKrXNKpWtKnGtKlGNKjG'.
'NKhGNKhFJKc1pKa1JCrWtCpWtCnGtClGNCjGNCjFpChFpCe1JC'.
'a1JCY1I5pWs5nGM5lGM5jFo5hFo5e1o5c0o5WkoxjFoxhFoxhF'.
'Ixe1Ixc1Ixc0oxa0ophFIpe0opc0opa0opa0IpY0IpWkIpWjkp'.
'UkIpUjkhc0oha0IhY0IhWjkhWjEhUjkhUjEhSjEhSikhQjEhQi'.
'kYWjkYSjEYSikYQjEYQikQSikQQikQQiEQOSExf8saAAAAAXRS'.
'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'.
'LdfvwAAAAHdElNRQfTAwkRFCaDkWqUAAAB+ElEQVR4nI3S+1vS'.
'UBgHcGZlPV0ks/vFrmQWFimJjiwiYUJWjFBWFhClyZCy5hLrwA'.
'x2EIwJC1w7zf2vnU0re+iHvs9++7x7zznvORbLf+TA6ct9fYMX'.
'jrfAUYefpp+/iM1ykxf/lmuhUZ/PTwXC8dml5Wcd23o5H5Mk6b'.
'5NUU8icXbhS67rNzn9JDnguOEYGQtEEtwC+Crs3RJ76P5A/znr'.
'vsNX7wQnEiwHCtK7TTkW8rvdZ9uJtvZTLkxpHhSrP66bNEj7/P'.
'3WNoLYeeSWQQCIpe9lQw7RNEU5rDsIYtcJ14Nocg7kRUlBNkxn'.
'YmGKcp7cv3vPwR7XOJPmc0VYU3Sv0e9NOBAYG7Hbz/cMjTMveZ'.
'CHkqxuTBv0PhYJB4N3XR6PJ5rMAPMnpGUxDX1IxSeMTEaZp1OZ'.
'nGAIQiYtsalUIhFlmGTy3sO3AizJCKn6DKYryxzHsWyaneMzr6'.
'cWxRVZVlFTe4SpE3zm+U/4+whyiwJcWVMQNr3XONirVWAklxcE'.
'EdbqchPhjhVzGpeqhUKhWBQhLElr9fo3pDaQPrw5xOl1CGG1JE'.
'k1uYEBIVkrb02+o6RItfq6rBhbw/tuINT96766KhuqYpY3UFPF'.
'BbY/19yZ1XF1U0UNBa9T7rZsz80K0jWk6bpWGW55UzbvTHZ+3t'.
'vbAv/IT+K1uCmhIrKJAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bl_green.png
//==========================================================
$this->imgdata_large[8][0]= 1484 ;
$this->imgdata_large[8][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMMFjM4kcoDJQAABVlJREFUeNq9ll2MJFUVx3/11V'.
'Vd/TE9vU0v4zLDwJIF16jBqLAPhsRXEiDqg0QTJiQSjcSNvCzw'.
'sBEDDxizhvAAxBgf1oR9QF9NiE9ESFZkQyZB5WtddmdnZ3qqqr'.
'uqbt367Cofqu3ZZpWVaDzJfbkf53//55z/PVdZXV3l/2H6f7Lp'.
'5VdOV/4Nb+GmHpUeA7AdBNxc3kafNb73jRPK9Xwon8ToxVefqU'.
'b91wibH5EkCQBCizFihTSviHUHR0hWws9xe3wvJ7/7nPKpgX5y'.
'9oFqt3eOgWniRBoAbUBGGqZUibSYaeoT2B5bnkdaSA6793Cv/S'.
'QPPbihXBfo5VdOV+8dfgnvwAU62YH5fCZ12sDujFkwyegCqTrB'.
'iUOKTOJKj8jr88jS8zy6cXwBTP048nuHX0I0nDlIp7RpTG7kM0'.
'sdyAYsTVukUuWGhlWHMq0ITL92lnUp9R1Obz/GmTNnqn9bDD8/'.
'+0D1oX0O0zQZZDYCsK2j3Gl9jQqDfHiei8GfiKVLlsZkJaBAN1'.
'0i6PgwUbB0GxG5/PrtE/xLRr959Znqw9452oVNI+jiJhnr1pe4'.
'k29zB1/nFr5Kj7tpt1YYhJ0FJ7nUYbcJQBgahN2MzeCP/OipR6'.
'prgN6Qr6ELFQFUWoRpNVjlKwxZB8DCpE+PtfEKqV1cUzxpVudu'.
'GTBHA5Y1g99e+dUio9O/P1Vpq+/WE5GGjDSMoAtAQjrf3C52IP'.
'QxpY4WK2hpReka9Gfrhqgz0bACRoCWjDh56kQ1z9FeuUUQxVhK'.
'B92sD1VahM+bAJgcoJhGjP/6Ln8rAgDiRCVRKiIzxMkkodBJ85'.
'im1IlEHbE4k1xyNveL4YP8HarmGJIOpqyjeQmfNHmTvnqZTWBt'.
'vIJXpPwlukJSuSTKGK3pEwtJmiX00ZlInTyNscImO6XBITvH1c'.
'8vVt2OucdKvIyeKRTNCivsEMgcpg6taYs30nfq0Gqg6hOSSFJ4'.
'BSnJPht0IqEjWmOGocEI6F0J94F0qaL6BntTF0MtUfweKQKAPU'.
'Wwp4OcVnQAmVb0p9DLOzjEhEKnGRmoRc7EzRGlwA6NujAKG4yP'.
'6Sjwc4aVznZ7DK0xXdkDoJf0kGmFBniFBOBGcZSCCSKd0IwN0k'.
'IS+QZWCGVZex4BnUxya3+Zt9iugQbcRFpIAtuHvAZulPUdLhUJ'.
'RqegI3WcqaSXddlT3idsWMSRRGkEtNwmyTifAwyBo7LP+11J0e'.
'7tM7pZOYblHkBLcqZ5LcYtw6Wbd4CM3SpE9foYZsIHoqDKCrbz'.
'mLSQtPwmuhXgtBLs0GBdbXOhFGB7WBKO2F8GXt9/VO97Ya3atF'.
'7nUHnwGjGGQqcPxFEdFqURkEidiZszAERoYIsGju1hq21kWee3'.
'bw15+8WpsvAy3K1+i3JkkhZyPpxxjjPOsfOYiZ+TFhLPzQnHOU'.
'tpzGB2dgA4tscIkKIx19Cxg/fPL7vQJu47eXt1VvsDK8pwPueZ'.
'PuZoQMOqhRoJHSs0kKLBWjvjYinmeQGw1TaX1RFdfZ3LMzYLjA'.
'C++dkn6AaH2Nobk6cxEzdnuG0TdC8zvdJkN0hqkFkO/jwL0fxa'.
'so8sBcuFzQ+/+MRC+BeAHnpwQzn++ee5KT9Eshuy46dcKAXm32'.
'0uzPQhS4GttkH2GQID2Wc0Y4LtAbDxhZ/x5A+e/uTG9+jGceXH'.
'9/ySnnIXnUzOxXe1038mW3ZynNmam4yYWkO+f9cv+Oljz16/lV'.
'9tDz/9nerc1hm8ZEScSRK7VvtYl1i1dklsOKyvc+zg/bzw1O8+'.
'/efkajt56kR1ydlEJBc5H46xzbrJ3dY9wrB7hGcff+6/+279L+'.
'0fHxyiE8XMLl4AAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bl_blue.png
//==========================================================
$this->imgdata_large[9][0]= 1169 ;
$this->imgdata_large[9][1]=
'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAACEF'.
'BMVEX/////////7//35//v1v/exv/Wvf/Wrf/Wpf/Orf+/v7+9'.
'tc69jP+9hP+5ucW1tc6tlP+rq7Wlpdalpcalpb2cnM6cnMacc/'.
'+cWv+UlLWUjN6UjK2Uc/+Ma/+MUv+EhKWEa/+EQvd7e8Z7e7V7'.
'e6V7c957Wv9za9Zza8ZzSv9ra5xrSv9rOf9rMe9jUudjQv9jOe'.
'9aWpRaUt5aUpRaSu9aSudSUoxSSs5SSoxSMf9KQtZKOfdKMedK'.
'Kf9KKe9CKf9CKb1CKa1CIfdCIedCId45MXs5Kfc5If85Iec5Id'.
'Y5GP8xMbUxMXsxKc4xKZQxIf8xGP8xGO8xGN4xGNYxGL0xGK0p'.
'KXMpIYwpGP8pGO8pGOcpGNYpGM4pEP8pEPcpEOcpEN4pENYpEM'.
'YpEL0hGKUhEP8hEPchEO8hEOchEN4hENYhEM4hEMYhELUhCP8h'.
'CO8hCN4YGJwYGGsYEL0YEK0YEHMYCN4YCM4YCMYYCL0YCKUYAP'.
'8QEJQQEIwQEHsQEGsQCM4QCLUQCK0QCKUQCJwQCJQQCIwQCHMQ'.
'CGsQAP8QAPcQAO8QAOcQAN4QANYQAM4QAMYQAL0QALUQAKUQAJ'.
'QQAIQICGsICGMIAO8IANYIAL0IALUIAK0IAKUIAJwIAJQIAIwI'.
'AIQIAHsIAHMIAGsIAGMAAN4AAMYAAK0AAJQAAIwAAIQAAHMAAG'.
'sAAGMAAFrR1dDlAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'.
'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkRFRPMOZ'.
'/2AAAB+klEQVR4nGNgIAIIqeqZmBqpi2JISNml5lVXV3d198Yo'.
'oUjwm1SnxsbGRsSm5ZfNXO4tjCTjVh0ABhFx6QV9E1Y0S8JkuN'.
'3yAgLc7W3t/QPi4jPKJ8ye1yoIlTKpjvVy15eVUbN0i4zKLJ8w'.
'ae6qcKgLqmMj3PUFWFl5NJ0CExLLJzbNW7BWCyxlXR0ba6/Axs'.
'zELmfnkRBT0QiSKgXJCOflxUbYy3KyMHEoOrtEZ1c2TZ6/cMl6'.
'eaCUamdsbIC7tjgPr4SBS3BMMVDTwkXr1hsDpYy6UmMj/O0tdX'.
'QNbDxjknJLWqYsXLx0vStQynxGflpkZGCgs7Onp29SbtNkoMy6'.
'pevCgFJWy3oyMuKjgoKCPWNCvEuqWhcsWrJ06XqQlPnMvrKyrM'.
'TomJjkZAfHlNa2qdOWrlu63gcopbG8v7+hvLwip7g4JdSxsLZu'.
'8dKlS9ettwBKic2eNXHChIkTG5tKqgpr2uo6loLAehWQx0LnzJ'.
'49p6mpeXLLlNq6RUvqly6dvnR9Bx9ISnnlvLmT582bMr9t4aL2'.
'+vrp60GaDCGB6Ld6wfwFCxYCJZYsXQ+SmL6+FBryInVrFi1atH'.
'jJkqVQsH6pNCzCJNvXrQW6CmQJREYFEc2CYevXrwMLAyXXl0oz'.
'IAOt0vVQUGSIkabkDV3DwlzNVDAksAAAfUbNQRCwr88AAAAASU'.
'VORK5CYII=' ;
 
//==========================================================
// File: bs_red.png
//==========================================================
$this->imgdata_small[0][0]= 437 ;
$this->imgdata_small[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAk1'.
'BMVEX////////GxsbGra3/xsbOhITWhIT/hIT/e3v/c3P/a2vG'.
'UlK1SkrOUlL/Y2PWUlLGSkrnUlLeSkrnSkr/SkqEGBj/KSmlGB'.
'jeGBjvGBj3GBj/EBD/CAj/AAD3AADvAADnAADeAADWAADOAADG'.
'AAC9AAC1AACtAAClAACcAACUAACMAACEAAB7AABzAABrAABjAA'.
'BuukXBAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGDNEMgOYAAAAm0'.
'lEQVR4nI3Q3RKCIBAFYGZMy9RKzX7MVUAUlQTe/+kS0K49d3wD'.
'7JlFaG+CvIR3FvzPXgpLatxevVVS+Jzv0BDGk/UJwOkQ1ph2g/'.
'Ct5ACX4wNT1o/zzUoJUFUGBiGfVnDTYGJgmrWy8iKEtp0Bpd2d'.
'jLGu56MB7f4JOOfDJAwoNwslk/jOUi+Jts6RVNrC1hkhPy50Ef'.
'u79/ADQMQSGQ8bBywAAAAASUVORK5CYII=' ;
 
 
//==========================================================
// File: bs_lightblue.png
//==========================================================
$this->imgdata_small[1][0]= 657 ;
$this->imgdata_small[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABVl'.
'BMVEX////////d///AwMC7wcS08P+y+P+xxdCwxM+uws2twMur'.
'vsinzNynytylzuKhyN6e5v6d5P+d1fOcwNWcu8ub4f+at8iZ3v'.
'+ZvdGY2/yW2f+VscGU1vuT1fqTr72Sx+SSxeKR0fWRz/GPz/OP'.
'rr+OyeqMy+6Myu2LyeyKxueJudSGw+SGorGDvt+Cvd6CvN2Aud'.
'p+uNd+t9Z9tdV8tdR8tNN6sc94r813rct2q8h0qcZ0qMVzp8Rx'.
'o8Bwor5tn7ptnrptnrlsnbhqmbRpmbNpi51ol7Flkqtkkqtkka'.
'pjj6hijaRhjaZgi6NfiqJfiaFdh55bhJtag5pZgphYgJZYf5VX'.
'cn9Ve5FSeI1RdopRdYlQdYlPc4dPcoZPcoVNcINLboBLbH9GZn'.
'hGZXdFZHZEY3RDYnJCXW4/W2s/WWg+Wmo7VmU7VGM7U2E6VGM6'.
'VGI5UV82T1wGxheQAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'.
'gAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGTok'.
'9Yp9AAAAtElEQVR4nGNgIBaw8wkpKghzwvksPAKiUsraprYiLF'.
'ARXkE2JiZ1PXMHXzGIAIekOFBE08TGLTCOCyzCLyvDxsZqZOnk'.
'E56kAhaRV9NQUjW2tPcMjs9wBYsY6Oobmlk7egRGpxZmgkW0zC'.
'2s7Jy9giKT8gohaiQcnVzc/UNjkrMLCyHmcHr7BYREJKTlFxbm'.
'QOxiEIuKTUzJKgQCaZibpdOzQfwCOZibGRi4dcJyw3S4iQ4HAL'.
'qvIlIAMH7YAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bs_gray.png
//==========================================================
$this->imgdata_small[2][0]= 550 ;
$this->imgdata_small[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAMAAADH72RtAAABI1'.
'BMVEX///8AAAD8EAD8IAD8NAD8RAD8VAAYGBi/v7+goKCCgoJk'.
'ZGRGRkb8yAD83AD87AD8/AD4+ADo+ADY+ADI+AC0+ACk+ACU+A'.
'CE+AB0/ABk/ABU/ABE/AAw/AAg/AAQ/AAA/AAA+AAA6BAA2CAA'.
'yDQAtEQApFQAlGQAhHQAdIgAZJgAVKgARLgAMMgAINwAEOwAAP'.
'wAAPgIAPAQAOgYAOAkANgsANA0AMg8AMBEALhMALBUAKhcAKBo'.
'AJhwAJB4AIiAAID////4+Pjy8vLs7Ozm5ubg4ODa2trT09PNzc'.
'3Hx8fBwcG7u7u1tbWurq6oqKiioqKcnJyWlpaQkJCJiYmDg4N9'.
'fX13d3dxcXFra2tkZGReXl5YWFhSUlJMTExGRkZAQEA1BLn4AA'.
'AAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIA'.
'AAsSAdLdfvwAAAAHdElNRQfTAwkUGiIctEHoAAAAfElEQVR4nI'.
'2N2xKDIAwF+bZ2kAa8cNFosBD//yvKWGh9dN+yk9kjxH28R7ze'.
'wzBOYSX6CaNB927Z9qZ66KTSNmBM7UU9Hx2c5qjmJaWCaV5j4t'.
'o1ANr40sn5a+x4biElrqHgrXMeac/c1nEpFHG0LSFoo/jO/BeF'.
'lJnFbT58ayUf0BpA8wAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bs_greenblue.png
//==========================================================
$this->imgdata_small[3][0]= 503 ;
$this->imgdata_small[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAxl'.
'BMVEX///////+/v79znJQhSkJ7raU5hHtjraVKnJRCjIRClIyU'.
'9++E595avbVaxr2/v7+ctbWcvb17nJxrjIx7paUxQkK9//+Mvb'.
'17ra2Evb17tbVCY2MQGBiU5+ec9/eM5+d71tZanJxjra1rvb1j'.
'tbVSnJxara1rzs5jxsZKlJRChIQpUlIhQkJatbVSpaU5c3MxY2'.
'MYMTEQISFavb1Sra1KnJxCjIw5e3sxa2spWlpClJQhSkoYOTkp'.
'Y2MhUlIQKSkIGBgQMTH+e30mAAAAAXRSTlMAQObYZgAAAAFiS0'.
'dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfT'.
'AwkUGTIqLgJPAAAAqklEQVR4nI2QVxOCMBCEM6Mi2OiCvSslJB'.
'CUoqjn//9TYgCfubf9Zu9uZxFqO+rscO7b6l/LljMZX29J2pNr'.
'YjmX4ZaIEs2NeiWO19NNacl8rHAyD4LR6jjw6PMRdTjZE0JOiU'.
'dDv2ALTlzRvSdCCfAHGCc7yRPSrAQRQOWxKc3C/IUjBlDdUcM8'.
'97vFGwBY9QsZGBc/A4DWZNbeXIPWZEZI0c2lqSute/gCO9MXGY'.
'4/IOkAAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bs_yellow.png
//==========================================================
$this->imgdata_small[4][0]= 507 ;
$this->imgdata_small[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAzF'.
'BMVEX///////+/v79zYwCMewDOxoTWzoTezkr/5wj/5wDnzgDe'.
'xgC1pQCtnACllACcjACUhABjWgDGvVK1rUrOxlLGvUqEexilnB'.
'jv3hj35xj/7wj/7wD35wDv3gDn1gDezgDWxgDOvQDGtQC9rQCE'.
'ewB7cwBzawBrYwDWzlLn3lLe1krn3kre1hi9tQC1rQCtpQClnA'.
'CclACUjACMhAD/9wC/v7///8bOzoT//4T//3v//3P//2v//2Pn'.
'50r//0r//yn39xj//xD//wBjYwDO8noaAAAAAXRSTlMAQObYZg'.
'AAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAH'.
'dElNRQfTAwkUGSDZl3MHAAAAqElEQVR4nI3QWRNDMBAA4My09E'.
'IF1SME0VT1okXvM/3//6kEfbZv+81eswA0DfHxRpOV+M+zkDGG'.
'rL63zCoJ2ef2RLZDIqNqYexyvFrY9ePkxGWdpvfzC7tEGtIRly'.
'nqzboFKMlizAXbNnZyiFUKAy4bZ+B6W0lRaQDLmg4h/k7eFwDL'.
'OWIky8qhXUBQ7gKGmsxpC+ah1TdriwByqG8GQNDNr6kLjf/wAx'.
'KgEq+FpPbfAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bs_darkgray.png
//==========================================================
$this->imgdata_small[5][0]= 611 ;
$this->imgdata_small[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAABJl'.
'BMVEX////////o8v/f6O7W4OnR3PXL1OTL0evEyLvCzePAwMC/'.
'v7a8wsq7t7C1xum1vtS1q6GzopmyxeKsrsOqvNWoq7anvN+nsb'.
'qhrcGgqbGfpq6cp7+bqMuVmJKRm7yPlKKMnL6FkKWFipOEkLSE'.
'j6qEhoqAiaB+jqd8haF7hZR4iJt4g5l3hZl2gIt2cod1hJVzeY'.
'VzboJvhp9sfJJsb41peY1pd5xpdoVod4xndI5lcHxka4BjcYVg'.
'Z3BfboFbb4lbZnZbYntaZ4laZYVZV3JYYWpXX3JWWm5VX4RVW2'.
'NUYX9SXHxPWn5OVFxNWWtNVXVMVWFKV3xHUGZGU3dGTldFSlxE'.
'Sk9ESXBCRlNBS3k/SGs/RU4+R1k9R2U6RFU2PUg0PEQxNU0ECL'.
'QWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAA'.
'CxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGQmbJetrAAAAtklEQV'.
'R4nGNgwAK4JZTNNOWlYDxhMT4ZDTOzQE1uMF9CiJWVU0LbxDlS'.
'G8QVF+FnZ2KRNHAIiPUHaZGSlmZj5lH19A1KjLUA8lXU5MWllF'.
'yjo30TYr2BfG19G11b37CEeN84H38gX1HbwTUkOjo+zjfG3hLI'.
'l1exCvCNCwnxjfMz0gTyRdXNHXx9fUNCQu2MwU6SN3ZwD42LCH'.
'W30IK4T8vUJSAkNMhDiwPqYiktXWN9JZj7UQAAjWEfhlG+kScA'.
'AAAASUVORK5CYII=' ;
 
 
//==========================================================
// File: bs_darkgreen.png
//==========================================================
$this->imgdata_small[6][0]= 666 ;
$this->imgdata_small[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABX1'.
'BMVEX////////l/+nAwMC86r+8wb28wby8wLy78sCzw7SywrSx'.
'wLKwvrGuvK+syK+ryq2rx62n36ym3aumxKmk2qij0Keh16ahva'.
'Og1aSguKKe06KeuaCetZ+d0KGdtZ+bz6Cay56ZyZ2Zwp2Zr5qZ'.
'rpqYwJuXyZuXrJmVw5mUxZiTxJeTw5eTq5WRwJWPtJKOvZKKuI'.
'6Kt42Kn4yJt42ItIuGsomFsYmEsIiEr4eDr4eBrIR/qoN+qIJ8'.
'poB7pH56o356on14nnt2nXl0mndzmnZzmXZymHVwlXNvlHJukn'.
'FtiHBqjm1qjW1oi2toiWpniWplh2hlhmdkhWdig2VggGNgf2Je'.
'fmFdfGBde19bbl1aeFxXdFpWclhVclhVcVdUcFZTb1VSbVRQal'.
'JPaVFKY0xKYkxJYUtIYEpHX0lEWkZCWERCV0NCVkM/U0A+U0A+'.
'UUA+UEA9Uj89UT48Tj45TDvewfrHAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'.
'RQfTAwkUGRjxlcuZAAAAtElEQVR4nGNgIBZw8osqqIpzw/msfI'.
'IiUmr6lo6SbFARASEOJiYtQ2uXADmIAJeEGFBE18LBMySBBywi'.
'LC/LwcFiZuvmH5WiAxZR0tRW1DC3dfYJS8zyAouYGBibWtm7+o'.
'TEpZfkgEX0rG3snNx9Q2NSCksgaqRd3Ty8gyLiU/NKSiDmcPsF'.
'BodHJ2UUlZTkQ+xikIlNSE7LLgECZagL2VQyc0H8YnV2uD94jS'.
'ILIo14iQ4HALarJBNwbJVNAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bs_purple.png
//==========================================================
$this->imgdata_small[7][0]= 447 ;
$this->imgdata_small[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAnF'.
'BMVEX///////+/v7/Gvca9rb3Grcb/xv+1hLWte629hL21e7XG'.
'hMbWhNbOe87We9b/hP//e/97OXv/c///a///Y/+cOZz/Sv/WOd'.
'bnOefvOe//Kf9jCGNrCGv/EP//CP/nCOf/AP/3APfvAO/nAOfe'.
'AN7WANbOAM7GAMa9AL21ALWtAK2lAKWcAJyUAJSMAIyEAIR7AH'.
'tzAHNrAGtjAGPP1sZnAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'.
'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGS'.
'o5QpoZAAAAnElEQVR4nI3Q2xJDMBAG4MyQokWrZz3oSkJISJH3'.
'f7dK0Gv/Xb7J7vyzCK0NjtPsHuH/2wlhTE7LnTNLCO/TFQjjIp'.
'hHAA6bY06LSqppMAY47x+04HXTba2kAFlmQKr+YuVDCGUG2k6/'.
'rNwYK8rKwKCnPxHnVS0aA3rag4UQslUGhrlk0Kpv1+sx3tLZ6w'.
'dtYemMkOsnz8R3V9/hB87DEu2Wos5+AAAAAElFTkSuQmCC' ;
 
 
//==========================================================
// File: bs_brown.png
//==========================================================
$this->imgdata_small[8][0]= 677 ;
$this->imgdata_small[8][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABaF'.
'BMVEX//////////8X/3oD/3nj/1HX/0Gr/xGP/rkv/gBf+iS/2'.
'bAL1agDxaQDuZwDrZwLpZQDmZQLlZADjcx7gZATeYQDdZgraXw'.
'DZXwHYXgDXiEvXZAvUjlfUXwXTjVfTbR7ShUvRbR7RWwDMWQDL'.
'WADKooLKWADJoYLJgkvHWATGoILFn4LFgEvFVgDEZx7EVQDDt6'.
'/DVQDCt6/CnoLChlfCVADAwMC+hFe+UgC8UgC6UQC4gVe4UAC3'.
'gVe3UAC1gFe1eUu1TwC1TgCzTgCwTQKuTACrSgCqSgCpSgCpSQ'.
'CodEulSACkRwCiRgCdRACcRACaQwCYQgCWQgKVQQCVQACUQACS'.
'UR6RPwCOPgCNPQCLPACKPACJOwCEOQCBOAB+NwB9NgB8NgB7NQ'.
'B6NwJ4NAB3RR52MwB0MgBuLwBtLwBsLwBqLgBpLQBkLQJiKgBh'.
'KgBgKwRcKABbKQJbJwBaKQRaJwBYKAJVJQDZvdIYAAAAAXRSTl'.
'MAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLd'.
'fvwAAAAHdElNRQfTAwkUGho0tvl2AAAAtklEQVR4nGNgIBaoSg'.
'mLKGpowfkGMty8AqJKpi4mRlAROR5ONg4JFUv3YHOIgDo/HwsT'.
'q6yps29EsjZYREFIkJ2ZS9/OMzA20wEsIi8uKSZtaOPmH5WSFw'.
'YW0VRW07Vw8vCLSMguLwCL6FlaObp6B0TGZxSXQ9TouHv6+IXG'.
'JGYWlpdDzNEKCgmPjkvLKS0vL4LYxWAen5SelV8OBNZQFxrZ5h'.
'aC+GX2MDczMBh7pZakehkTHQ4AA0Am/jsB5gkAAAAASUVORK5C'.
'YII=' ;
 
//==========================================================
// File: bs_blue.png
//==========================================================
$this->imgdata_small[9][0]= 436 ;
$this->imgdata_small[9][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAk1'.
'BMVEX///////+/v7+trcbGxv+EhM6EhNaEhP97e/9zc/9ra/9S'.
'UsZKSrVSUs5jY/9SUtZKSsZSUudKSt5KSudKSv8YGIQpKf8YGK'.
'UYGN4YGO8YGPcQEP8ICP8AAP8AAPcAAO8AAOcAAN4AANYAAM4A'.
'AMYAAL0AALUAAK0AAKUAAJwAAJQAAIwAAIQAAHsAAHMAAGsAAG'.
'ONFkFbAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGhNNakHSAAAAmk'.
'lEQVR4nI3P2xKCIBAGYGfM6SBWo1nauIqogaDA+z9dK9Lhrv47'.
'vtl/2A2CfxNlJRRp9IETYGraJeEb7ocLNKznia8A7Db7umWDUG'.
'sxAzhurxRHxok4KQGqCuEhlL45oU1D2w5BztY4KRhj/bCAsetM'.
'2uObjwvY8/oX50JItYDxSyZSTrO2mNhvGMbaWAevnbFIcpuTr7'.
't+5AkyfBIKSJHdSQAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bs_green.png
//==========================================================
$this->imgdata_small[10][0]= 452 ;
$this->imgdata_small[10][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAn1'.
'BMVEX///////+/v7+/v7/G/8aUxpSMvYyUzpSMzoyM1oxarVqE'.
'/4R7/3tavVpKnEpaxlpz/3Nr/2tKtUpj/2Na51pKzkpK1kpK50'.
'pK/0oYcxgp/ykYlBgY3hgY7xgY9xgQ/xAI/wgA/wAA9wAA7wAA'.
'5wAA3gAA1gAAzgAAxgAAvQAAtQAArQAApQAAnAAAlAAAjAAAhA'.
'AAewAAcwAAawAAYwA0tyxUAAAAAXRSTlMAQObYZgAAAAFiS0dE'.
'AIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAw'.
'kUGgW5vvSDAAAAnklEQVR4nI3QSxKCMAwA0M4gqCgoiiJ+kEAL'.
'LQUq0PufzX7ENdnlJZNkgtDS2CYZvK6bf+7EoKLA9cH5SQzv6A'.
'YloTywsAbYr44FrlgrXCMJwHl3xxVtuuFkJAPIcw2tGB9GcFli'.
'oqEf5GTkSUhVMw2TtD0XSlnDOw3SznE5520vNEi7CwW9+Ayjyq'.
'U/3+yPuq5gvhkhL0xlGnqL//AFf14UIh4mkEkAAAAASUVORK5C'.
'YII=' ;
 
 
//==========================================================
// File: bs_white.png
//==========================================================
$this->imgdata_small[11][0]= 480 ;
$this->imgdata_small[11][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAABm'.
'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'.
'B3RJTUUH0wMLFTsY/ewvBQAAAW1JREFUeJytkz2u4jAUhT/jic'.
'gfBUKiZhE0bIKeVbCWrIKenp6eDiGlCEEEBArIxvzGU4xeZjLk'.
'jWb05lRXuvbx+exr4bouX1Xjyw7Atz81F4uFBYjjGIDhcCjq1o'.
'k6nN1uZwFerxfP55Msy1itVmRZBsB4PK6YveHkeW5d18XzPIIg'.
'wPd9Wq0WnU6HMAxJkoQoiuynOIfDwUopkVIihKAoCgAcx6Hdbm'.
'OMIU1T5vN55eBKEikljUYDIX6kFUKU9e8aDAZlmjcca+1b7TgO'.
'1+uVy+VS9nzfr8e53++VzdZaiqIgz3OMMWitOZ/PaK0JgqDeRC'.
'mF53lIKYGfr3O73TDGoJQiTVO01nS73XqT4/FIs9kkCAIej0eZ'.
'brPZEMcxSZKgtQZgMpmIWpN+vy+m06n1PK9yTx8Gy+WS/X5Pr9'.
'er9GuHLYoiG4YhSilOpxPr9Zrtdlti/JriU5MPjUYjq7UuEWaz'.
'2d+P/b/qv/zi75oetJcv7QQXAAAAAElFTkSuQmCC' ;
 
 
//==========================================================
// File: bs_cyan.png
//==========================================================
$this->imgdata_small[12][0]= 633 ;
$this->imgdata_small[12][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABPl'.
'BMVEX////////F///AwMCvxsaC1NSC0dGCz8+CzMyA//94//91'.
'//9q//9j//9X4uJX09NXz89Xx8dXxMRL//9L5uZL3d1L2NhLxs'.
'ZLt7cv//8e9fUe8fEe7u4e398epqYehoYX//8L+PgK//8F9fUE'.
'/v4E5+cEb28EZ2cC//8C/v4C/f0CzMwCrq4Cjo4CdXUCaWkCZW'.
'UB/PwA//8A/f0A+/sA8/MA7e0A7OwA6+sA5eUA5OQA4uIA4eEA'.
'3NwA2toA2NgA1dUA09MA0tIA0NAAysoAxsYAxcUAxMQAv78Avr'.
'4AvLwAtrYAtbUAs7MAsLAAra0Aq6sAqKgApaUApKQAoqIAoKAA'.
'n58AmpoAlZUAk5MAkpIAkJAAj48AjIwAiYkAh4cAf38AfX0Ae3'.
'sAenoAcnIAcHAAa2sAaWkAaGgAYmIUPEuTAAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'.
'AHdElNRQfTAwkUGQDi+VPPAAAAtElEQVR4nGNgIBawikipyIiy'.
'wfksfJpGRkamNtr8LFARPiMFHmFDcztXfwGoFi0jLiZuZRtnry'.
'BddrCIiJEGL6eklYO7X3iCOFhE2thESdHawdUnJDZFDiyiamZh'.
'aevk5h0UlZSpBhaRtbN3dPHwDY5MSM+EqBFzc/f0DgiLTkjLzI'.
'SYw6bjHxgaEZeckZmpD7GLQSAqJj4xNRMIBGFuFtRLA/ENhGBu'.
'ZmDgkJBXl5fgIDocAAKcINaFePT4AAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bs_bluegreen.png
//==========================================================
$this->imgdata_small[13][0]= 493 ;
$this->imgdata_small[13][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAvV'.
'BMVEX///////+/v79j//855/8x3v851v9Spb1C1v8AOUqEtcZK'.
'lK1StdYxzv8hxv8AY4QASmNSlK1KpcZKtd4YQlIYnM4YrecIvf'.
'8AtfcAre8AjL0AhLUAc5wAa5QAWnsAQloAKTkAGCFKhJxKrdYY'.
'jL0Ypd4Atf8ArfcApecAnN4AlM4AjMYAe60Ac6UAY4wAUnNSnL'.
'0AlNYAWoQASmsAOVIAITGEtc4YWnsAUnsAMUqtvcaErcYAKUIA'.
'GCkAECHUyVh/AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAA'.
'AJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGxNUcXCT'.
'AAAAqUlEQVR4nI2Q1xKCMBREM2NHLCCogAGCjd6SqLT8/2cZKT'.
'6zb3tm987OBWCsXoejp8rC35fi4+l6gXFZlD0Rz6fZ1tdDmKR9'.
'RdOmkzmP7DDpilfX3SzvRgQ/Vr1uiZplfsCBiVf03RJd140wgj'.
'kmNqMtuYXcxyYmNWJdRoYwzpM9qRvGujuCmSR7q7ARY00/MiWk'.
'sCnjkobNEm1+HknDZgAqR0GKU43+wxdu2hYzbsHU6AAAAABJRU'.
'5ErkJggg==' ;
 
//==========================================================
// File: bs_lightred.png
//==========================================================
$this->imgdata_small[14][0]= 532 ;
$this->imgdata_small[14][1]=
'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAA3l'.
'BMVEX///////+/v7/Gvb0hGBj/5///3v//zu//1u//xucpGCG9'.
'nK21lKVSQkp7Wms5KTExISlaOUpjQlIhEBj/tdbOhKXnrcbGjK'.
'Wla4TetcbGnK2EWmv/rc73pcZ7UmOcY3vOpbW1jJzenLW9e5Rz'.
'Slq1c4xrQlJSOULGhJz/pcb3nL2chIzOnK33rcbelK3WjKWMWm'.
'vGe5SEUmM5ISnOtb3GrbXerb3vpb2ca3v/rcaUY3POhJxCKTF7'.
'SlrWnK21e4ytc4TvnLXnlK2la3taOUK1lJxrSlLGhJRjQkpSMT'.
'lw+q2nAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGjoP2Nm+AAAAr0'.
'lEQVR4nGNgIBaYiOk62imYwPnMkiIyso76yhJSzFARMxkRNk49'.
'a3t5OW6oFk1LVkYOfWUHKxUXiEYzLS12DnN3VXkjIRtFsIiSk5'.
'6evqGqhYGKugAfWMRa1FpD2UHeQEXQRlgALCJur+rgbCUNFOAS'.
'hqjRkZe3MpBTcwEKCEPMMTGSs3Xz8OQHCnBBHckt6OJpIyAMBD'.
'wwN/MYc4H4LK4wNzMwmGrzcvFqmxIdDgDiHRT6VVQkrAAAAABJ'.
'RU5ErkJggg==' ;
 
//==========================================================
// File: bxs_lightred.png
//==========================================================
$this->imgdata_xsmall[0][0]= 432 ;
$this->imgdata_xsmall[0][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAA3l'.
'BMVEX///////+/v7/Gvb0hGBj/5///3v//zu//1u//xucpGCG9'.
'nK21lKVSQkp7Wms5KTExISlaOUpjQlIhEBj/tdbOhKXnrcbGjK'.
'Wla4TetcbGnK2EWmv/rc73pcZ7UmOcY3vOpbW1jJzenLW9e5Rz'.
'Slq1c4xrQlJSOULGhJz/pcb3nL2chIzOnK33rcbelK3WjKWMWm'.
'vGe5SEUmM5ISnOtb3GrbXerb3vpb2ca3v/rcaUY3POhJxCKTF7'.
'SlrWnK21e4ytc4TvnLXnlK2la3taOUK1lJxrSlLGhJRjQkpSMT'.
'lw+q2nAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUKBOgGhWjAAAAS0'.
'lEQVR4nGNgQAEmunYmEJaMCKe1vBxYzJKVQ9lKBSSupKdnaKGi'.
'zgdkiqs6WKnYcIGYJnK2HvzCwmCNgi42wsLCECNMeXlNUY0HAL'.
'DaB7Du8MiEAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bxs_bluegreen.png
//==========================================================
$this->imgdata_xsmall[1][0]= 397 ;
$this->imgdata_xsmall[1][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAvV'.
'BMVEX///////+/v79j//855/8x3v851v9Spb1C1v8AOUqEtcZK'.
'lK1StdYxzv8hxv8AY4QASmNSlK1KpcZKtd4YQlIYnM4YrecIvf'.
'8AtfcAre8AjL0AhLUAc5wAa5QAWnsAQloAKTkAGCFKhJxKrdYY'.
'jL0Ypd4Atf8ArfcApecAnN4AlM4AjMYAe60Ac6UAY4wAUnNSnL'.
'0AlNYAWoQASmsAOVIAITGEtc4YWnsAUnsAMUqtvcaErcYAKUIA'.
'GCkAECHUyVh/AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAA'.
'AJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUKDVyF5Be'.
'AAAASUlEQVR4nGNgQAFmYqJcEJaEOJ+UrD5YTJKFTZrfGCQuaq'.
'glLWvMaQ5kqujo6hnbKIKYXPr68gp2dmCNJiZAlh3ECGsREWtU'.
'4wF1kwdpAHfnSwAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bxs_navy.png
//==========================================================
$this->imgdata_xsmall[2][0]= 353 ;
$this->imgdata_xsmall[2][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAk1'.
'BMVEX///////+/v7+trcbGxv+EhM6EhNaEhP97e/9zc/9ra/9S'.
'UsZKSrVSUs5jY/9SUtZKSsZSUudKSt5KSudKSv8YGIQpKf8YGK'.
'UYGN4YGO8YGPcQEP8ICP8AAP8AAPcAAO8AAOcAAN4AANYAAM4A'.
'AMYAAL0AALUAAK0AAKUAAJwAAJQAAIwAAIQAAHsAAHMAAGsAAG'.
'ONFkFbAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUJxXO4axZAAAAR0'.
'lEQVR4nGNgQAGskhKsEJaslIi8ijpYTJaDU1FVAyQuKSujoKKh'.
'LQ5kSigpqWro6oOYrOoaWroGBmCNWiCWAdQwUVFWVOMBOp4GCJ'.
's5S60AAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bxs_gray.png
//==========================================================
$this->imgdata_xsmall[3][0]= 492 ;
$this->imgdata_xsmall[3][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABI1'.
'BMVEX///8AAAD8EAD8IAD8NAD8RAD8VAAYGBi/v7+goKCCgoJk'.
'ZGRGRkb8yAD83AD87AD8/AD4+ADo+ADY+ADI+AC0+ACk+ACU+A'.
'CE+AB0/ABk/ABU/ABE/AAw/AAg/AAQ/AAA/AAA+AAA6BAA2CAA'.
'yDQAtEQApFQAlGQAhHQAdIgAZJgAVKgARLgAMMgAINwAEOwAAP'.
'wAAPgIAPAQAOgYAOAkANgsANA0AMg8AMBEALhMALBUAKhcAKBo'.
'AJhwAJB4AIiAAID////4+Pjy8vLs7Ozm5ubg4ODa2trT09PNzc'.
'3Hx8fBwcG7u7u1tbWurq6oqKiioqKcnJyWlpaQkJCJiYmDg4N9'.
'fX13d3dxcXFra2tkZGReXl5YWFhSUlJMTExGRkZAQEA1BLn4AA'.
'AAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEA'.
'AAsRAX9kX5EAAAAHdElNRQfTAwkUKC74clmyAAAAQklEQVR4nG'.
'NgQAVBYVCGt5dXYEQ0mOnp5h4QFgVmeri6+4dHxYMVeHoFRUTH'.
'gTUFBIZBWAwMkZEx8bFQM2Lj0UwHANc/DV6yq/BiAAAAAElFTk'.
'SuQmCC' ;
 
//==========================================================
// File: bxs_graypurple.png
//==========================================================
$this->imgdata_xsmall[4][0]= 542 ;
$this->imgdata_xsmall[4][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABSl'.
'BMVEX////////11P/MqdvKrNfAwMC+u7+9u7+4rr24lsi3rby3'.
'lMe1rLq1o720q7i0oL20ksSzoryyqbaykMGxlb2wkL+vnbiujb'.
'2sjLuri7qpl7GoirWoibenmK2mla6mjLKmhrSllauki7CjhrCj'.
'hLGihLChg6+ggq2fkqadkKOcfqqai6Gag6WYe6WXeqSWeaOTd6'.
'CTd5+Rdp6RdZ6RdZ2Qg5eOc5qMcpiLcZeJb5WIbpOHbZKGbJGE'.
'a4+CaY2AZ4t/Z4p/Zop/Zol+Zol7ZIZ6Y4V5YoR1ZH11X391Xn'.
'9zXX1yXXtxXHtvWnluWXhsV3VqVnNpVXJoVHFnU3BmUm9jUGth'.
'VGdgTmheTGZcS2RcSmRaSWJYR19XRl5SQllRQlhQQVdPQFZOP1'.
'VLPlFJO09IPE5IOk5FOEtEN0lDOEpDOElDNklCNkc/M0XhbrfD'.
'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'.
'EAAAsRAX9kX5EAAAAHdElNRQfTAwkUKCgREfyHAAAATUlEQVR4'.
'nGNgQAEcIko8EBY3M5Ougy+IxSXMwmTsFsAHZMqrSRvZB0W7A5'.
'k6FlYugXEZICaPr394Um4uSAFDRFRCbm4uxAihsDAhVOMBHT0L'.
'hkeRpo8AAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bxs_red.png
//==========================================================
$this->imgdata_xsmall[5][0]= 357 ;
$this->imgdata_xsmall[5][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAk1'.
'BMVEX////////GxsbGra3/xsbOhITWhIT/hIT/e3v/c3P/a2vG'.
'UlK1SkrOUlL/Y2PWUlLGSkrnUlLeSkrnSkr/SkqEGBj/KSmlGB'.
'jeGBjvGBj3GBj/EBD/CAj/AAD3AADvAADnAADeAADWAADOAADG'.
'AAC9AAC1AACtAAClAACcAACUAACMAACEAAB7AABzAABrAABjAA'.
'BuukXBAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'.
'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUIyjy5SVMAAAAS0'.
'lEQVR4nGNgQAFsUpJsEJastIi8ijpYTJaDU0FVgxXIlJKVUVDR'.
'0BYHMiUUlVQ1dPVBTDZ1dS1dAwOQAgYtbSDLAGIEq6goK6rxAD'.
'yXBg73lwGUAAAAAElFTkSuQmCC' ;
 
//==========================================================
// File: bxs_yellow.png
//==========================================================
$this->imgdata_xsmall[6][0]= 414 ;
$this->imgdata_xsmall[6][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAzF'.
'BMVEX///////+/v79zYwCMewDOxoTWzoTezkr/5wj/5wDnzgDe'.
'xgC1pQCtnACllACcjACUhABjWgDGvVK1rUrOxlLGvUqEexilnB'.
'jv3hj35xj/7wj/7wD35wDv3gDn1gDezgDWxgDOvQDGtQC9rQCE'.
'ewB7cwBzawBrYwDWzlLn3lLe1krn3kre1hi9tQC1rQCtpQClnA'.
'CclACUjACMhAD/9wC/v7///8bOzoT//4T//3v//3P//2v//2Pn'.
'50r//0r//yn39xj//xD//wBjYwDO8noaAAAAAXRSTlMAQObYZg'.
'AAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAH'.
'dElNRQfTAwkUIzoBXFQEAAAAS0lEQVR4nGNgQAFsDhJsEJaTo5'.
'2skj5YzMnSSk7ZwBzIlOSUklPiMxYHMnW4FXT5VNVBTDZeXiNV'.
'QUGQAgYBYyBLEGIEq5gYK6rxAH4kBmHBaMQQAAAAAElFTkSuQm'.
'CC' ;
 
//==========================================================
// File: bxs_greenblue.png
//==========================================================
$this->imgdata_xsmall[7][0]= 410 ;
$this->imgdata_xsmall[7][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAxl'.
'BMVEX///////+/v79znJQhSkJ7raU5hHtjraVKnJRCjIRClIyU'.
'9++E595avbVaxr2/v7+ctbWcvb17nJxrjIx7paUxQkK9//+Mvb'.
'17ra2Evb17tbVCY2MQGBiU5+ec9/eM5+d71tZanJxjra1rvb1j'.
'tbVSnJxara1rzs5jxsZKlJRChIQpUlIhQkJatbVSpaU5c3MxY2'.
'MYMTEQISFavb1Sra1KnJxCjIw5e3sxa2spWlpClJQhSkoYOTkp'.
'Y2MhUlIQKSkIGBgQMTH+e30mAAAAAXRSTlMAQObYZgAAAAFiS0'.
'dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfT'.
'AwkUJy5/6kV9AAAATUlEQVR4nGNgQAGCyuyCEJaGugKHviVYzF'.
'hO3sxCWwDIVNLTM9PXtpEGMhW12Cy0DR1ATEFLSxZ7BweQAgYd'.
'HUMHBweIEQKiogKoxgMAo/4H5AfSehsAAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bxs_purple.png
//==========================================================
$this->imgdata_xsmall[8][0]= 364 ;
$this->imgdata_xsmall[8][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAnF'.
'BMVEX///////+/v7/Gvca9rb3Grcb/xv+1hLWte629hL21e7XG'.
'hMbWhNbOe87We9b/hP//e/97OXv/c///a///Y/+cOZz/Sv/WOd'.
'bnOefvOe//Kf9jCGNrCGv/EP//CP/nCOf/AP/3APfvAO/nAOfe'.
'AN7WANbOAM7GAMa9AL21ALWtAK2lAKWcAJyUAJSMAIyEAIR7AH'.
'tzAHNrAGtjAGPP1sZnAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'.
'HUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUIj'.
'mBTjT/AAAASUlEQVR4nGNgQAGskhKsEJaCrJiSuhZYTEFASFlD'.
'GyQuqSCnrK6tJwpkiquoamgbGIGYrFpaugbGxmCNunpAljHECB'.
'ZBQRZU4wFSMAZsXeM71AAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bxs_green.png
//==========================================================
$this->imgdata_xsmall[9][0]= 370 ;
$this->imgdata_xsmall[9][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAn1'.
'BMVEX///////+/v7+/v7/G/8aUxpSMvYyUzpSMzoyM1oxarVqE'.
'/4R7/3tavVpKnEpaxlpz/3Nr/2tKtUpj/2Na51pKzkpK1kpK50'.
'pK/0oYcxgp/ykYlBgY3hgY7xgY9xgQ/xAI/wgA/wAA9wAA7wAA'.
'5wAA3gAA1gAAzgAAxgAAvQAAtQAArQAApQAAnAAAlAAAjAAAhA'.
'AAewAAcwAAawAAYwA0tyxUAAAAAXRSTlMAQObYZgAAAAFiS0dE'.
'AIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAw'.
'kUKBrZxq0HAAAATElEQVR4nGNgQAGccrIcEJaivISyhjaIxa7I'.
'I6CiqcMKZMopKqho6OhLA5kyqmqaOobGICartraeoYkJSAGDnj'.
'6QZQIxgk1Skg3VeABlVgbItqEBUwAAAABJRU5ErkJggg==' ;
 
//==========================================================
// File: bxs_darkgreen.png
//==========================================================
$this->imgdata_xsmall[10][0]= 563 ;
$this->imgdata_xsmall[10][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABX1'.
'BMVEX////////l/+nAwMC86r+8wb28wby8wLy78sCzw7SywrSx'.
'wLKwvrGuvK+syK+ryq2rx62n36ym3aumxKmk2qij0Keh16ahva'.
'Og1aSguKKe06KeuaCetZ+d0KGdtZ+bz6Cay56ZyZ2Zwp2Zr5qZ'.
'rpqYwJuXyZuXrJmVw5mUxZiTxJeTw5eTq5WRwJWPtJKOvZKKuI'.
'6Kt42Kn4yJt42ItIuGsomFsYmEsIiEr4eDr4eBrIR/qoN+qIJ8'.
'poB7pH56o356on14nnt2nXl0mndzmnZzmXZymHVwlXNvlHJukn'.
'FtiHBqjm1qjW1oi2toiWpniWplh2hlhmdkhWdig2VggGNgf2Je'.
'fmFdfGBde19bbl1aeFxXdFpWclhVclhVcVdUcFZTb1VSbVRQal'.
'JPaVFKY0xKYkxJYUtIYEpHX0lEWkZCWERCV0NCVkM/U0A+U0A+'.
'UUA+UEA9Uj89UT48Tj45TDvewfrHAAAAAXRSTlMAQObYZgAAAA'.
'FiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElN'.
'RQfTAwkUKCFozUQjAAAATUlEQVR4nGNgQAGcoqrcEJYQB5OhSw'.
'CIxSXGwWThGcIDZCppK5o7hyV6AZl6NnbuoSmFICZ3YHB0RkkJ'.
'SAFDbEJaSUkJxAjeyEheVOMBQj4MOEkWew4AAAAASUVORK5CYI'.
'I=' ;
 
//==========================================================
// File: bxs_cyan.png
//==========================================================
$this->imgdata_xsmall[11][0]= 530 ;
$this->imgdata_xsmall[11][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABPl'.
'BMVEX////////F///AwMCvxsaC1NSC0dGCz8+CzMyA//94//91'.
'//9q//9j//9X4uJX09NXz89Xx8dXxMRL//9L5uZL3d1L2NhLxs'.
'ZLt7cv//8e9fUe8fEe7u4e398epqYehoYX//8L+PgK//8F9fUE'.
'/v4E5+cEb28EZ2cC//8C/v4C/f0CzMwCrq4Cjo4CdXUCaWkCZW'.
'UB/PwA//8A/f0A+/sA8/MA7e0A7OwA6+sA5eUA5OQA4uIA4eEA'.
'3NwA2toA2NgA1dUA09MA0tIA0NAAysoAxsYAxcUAxMQAv78Avr'.
'4AvLwAtrYAtbUAs7MAsLAAra0Aq6sAqKgApaUApKQAoqIAoKAA'.
'n58AmpoAlZUAk5MAkpIAkJAAj48AjIwAiYkAh4cAf38AfX0Ae3'.
'sAenoAcnIAcHAAa2sAaWkAaGgAYmIUPEuTAAAAAXRSTlMAQObY'.
'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAA'.
'AHdElNRQfTAwkUKQFKuFWqAAAATUlEQVR4nGNgQAGsUjJsEJaR'.
'grC5qz9YzIiL28YriB3IlDZRsnYNiZUDMmXtHT2CE9JBTDb/wI'.
'jkzEyQAoaomMTMzEyIERzy8hyoxgMAN2MLVPW0f4gAAAAASUVO'.
'RK5CYII=' ;
 
//==========================================================
// File: bxs_orange.png
//==========================================================
$this->imgdata_xsmall[12][0]= 572 ;
$this->imgdata_xsmall[12][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABaF'.
'BMVEX//////////8X/3oD/3nj/1HX/0Gr/xGP/rkv/gBf+iS/2'.
'bAL1agDxaQDuZwDrZwLpZQDmZQLlZADjcx7gZATeYQDdZgraXw'.
'DZXwHYXgDXiEvXZAvUjlfUXwXTjVfTbR7ShUvRbR7RWwDMWQDL'.
'WADKooLKWADJoYLJgkvHWATGoILFn4LFgEvFVgDEZx7EVQDDt6'.
'/DVQDCt6/CnoLChlfCVADAwMC+hFe+UgC8UgC6UQC4gVe4UAC3'.
'gVe3UAC1gFe1eUu1TwC1TgCzTgCwTQKuTACrSgCqSgCpSgCpSQ'.
'CodEulSACkRwCiRgCdRACcRACaQwCYQgCWQgKVQQCVQACUQACS'.
'UR6RPwCOPgCNPQCLPACKPACJOwCEOQCBOAB+NwB9NgB8NgB7NQ'.
'B6NwJ4NAB3RR52MwB0MgBuLwBtLwBsLwBqLgBpLQBkLQJiKgBh'.
'KgBgKwRcKABbKQJbJwBaKQRaJwBYKAJVJQDZvdIYAAAAAXRSTl'.
'MAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9k'.
'X5EAAAAHdElNRQfTAwkUJBSSy88MAAAATUlEQVR4nGNgQAGqwo'.
'paEBYPJ4eKezCIpc7HwmrqG6ENZMpLihm6RaWEAZl6Vo7ekRnF'.
'IKZWSHhcTnk5SAFDfFJWeXk5xAjj1FRjVOMBeFwNcWYSLjsAAA'.
'AASUVORK5CYII=' ;
 
//==========================================================
// File: bxs_lightblue.png
//==========================================================
$this->imgdata_xsmall[13][0]= 554 ;
$this->imgdata_xsmall[13][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABVl'.
'BMVEX////////d///AwMC7wcS08P+y+P+xxdCwxM+uws2twMur'.
'vsinzNynytylzuKhyN6e5v6d5P+d1fOcwNWcu8ub4f+at8iZ3v'.
'+ZvdGY2/yW2f+VscGU1vuT1fqTr72Sx+SSxeKR0fWRz/GPz/OP'.
'rr+OyeqMy+6Myu2LyeyKxueJudSGw+SGorGDvt+Cvd6CvN2Aud'.
'p+uNd+t9Z9tdV8tdR8tNN6sc94r813rct2q8h0qcZ0qMVzp8Rx'.
'o8Bwor5tn7ptnrptnrlsnbhqmbRpmbNpi51ol7Flkqtkkqtkka'.
'pjj6hijaRhjaZgi6NfiqJfiaFdh55bhJtag5pZgphYgJZYf5VX'.
'cn9Ve5FSeI1RdopRdYlQdYlPc4dPcoZPcoVNcINLboBLbH9GZn'.
'hGZXdFZHZEY3RDYnJCXW4/W2s/WWg+Wmo7VmU7VGM7U2E6VGM6'.
'VGI5UV82T1wGxheQAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'.
'gAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUJziL'.
'PvAsAAAATUlEQVR4nGNgQAHsQgqcEJYgG5Oegy+IxSHOxmTiFs'.
'gFZMprKBnbB8e7AplaFlbOQUl5ICanX0BEWmEhSAFDVGxKYWEh'.
'xAjusDBuVOMBJO8LrFHRAykAAAAASUVORK5CYII=' ;
 
//==========================================================
// File: bxs_darkgray.png
//==========================================================
$this->imgdata_xsmall[14][0]= 574 ;
$this->imgdata_xsmall[14][1]=
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABm'.
'JLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsRAAALEQF/ZF+RAAAB'.
'iElEQVR42k3QPU8TYRwA8P//ebkXrgdIColXRAOEkJqbaExMut'.
'DBhE1GNjYHPg+DG6ODiU6QOLjVxITBcFKBYCstlAC2Bz17fe76'.
'vLD6+wg/1FpTRFR5lpaub/u1eGBGaAT4HneD4OlXx7avtDYUjT'.
'HQabd2Ti8e3vVSKzxrtHS32wIpFVldno22Nqvvg2Bhl0gp/aNm'.
'vJ3qqXAtLIva+ks1H0wqlSXi4+d6+OFTfRsAfHJx2d1od24rZP'.
'xP2HzopINr1mkesX7ccojqif0v9crxWXODZTno3+dNGA7uWLsd'.
'mUYU4fHJCViMG9umLBmM4L6fagZGg9QKfjZ+Qfy3C3G/B3mugF'.
'IHHNcDf64E3KJALApk2p8CSolUUqLjFkyxOGMsTtFyJ+Wz57NQ'.
'8DghS4sLB0svioeZZo7nPhFoUKZDIVFbglkTTnl5/rC8snjAkJ'.
'Bk/XV5LxHC/v7tR8jzTFPbg8LENK9WX0Vv31T2AEmCSmlKCCoh'.
'ROnP1U1tPFYjJBRcbtzSf+GPsFTAQBq1n4AAAABKdEVYdHNpZ2'.
'5hdHVyZQBiYzYyMDIyNjgwYThjODMyMmUxNjk0NWUzZjljOGFh'.
'N2VmZWFhMjA4OTE2ZjkwOTdhZWE1MzYyMjk0MWRkM2I5EqaPDA'.
'AAAABJRU5ErkJggg==' ;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_log.php
New file
0,0 → 1,282
<?php
/*=======================================================================
// File: JPGRAPH_LOG.PHP
// Description: Log scale plot extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_log.php 820 2006-12-14 01:04:01Z 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,$dummy) {
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.');
}
if( is_numeric($this->autoscale_min) ) {
$smin = round($this->autoscale_min);
$smax = ceil(log10($max));
if( $min >= $max ) {
JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.');
}
}
else {
$smin = floor(log10($min));
if( is_numeric($this->autoscale_max) ) {
$smax = round($this->autoscale_max);
if( $smin >= $smax ) {
JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.');
}
}
else
$smax = ceil(log10($max));
}
$this->Update($img,$smin,$smax);
}
//---------------
// PRIVATE METHODS
} // Class
 
//===================================================
// CLASS LogTicks
// Description:
//===================================================
class LogTicks extends Ticks{
var $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 */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_iconplot.php
New file
0,0 → 1,189
<?php
//=======================================================================
// File: JPGRAPH_ICONPLOT.PHP
// Description: PHP4 Graph Plotting library. Extension module.
// Created: 2004-02-18
// Ver: $Id: jpgraph_iconplot.php 838 2007-01-22 21:01:22Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
 
//===================================================
// CLASS IconPlot
// Description: Make it possible to add a (small) image
// to the graph
//===================================================
class IconPlot {
var $iHorAnchor='left',$iVertAnchor='top';
var $iX=0,$iY=0;
var $iFile='';
var $iScale=1.0,$iMix=100;
var $iAnchors = array('left','right','top','bottom','center');
var $iCountryFlag='',$iCountryStdSize=3;
var $iScalePosY=null,$iScalePosX=null;
var $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 CreateFromString($aStr) {
$this->iImgString = $aStr;
}
 
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 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') ) {
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);
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/gd_image.inc.php
New file
0,0 → 1,2161
<?php
//=======================================================================
// File: GD_IMAGE.INC.PHP
// Description: GD Instance of Image class
// Created: 2006-05-06
// Ver: $Id: gd_image.inc.php 1008 2008-06-13 23:20:44Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
//===================================================
// CLASS RGB
// Description: Color definitions as RGB triples
//===================================================
class RGB {
var $rgb_table;
var $img;
function RGB(&$aImg) {
$this->img = &$aImg;
// Conversion array between color names and RGB
$this->rgb_table = array(
"aqua"=> array(0,255,255),
"lime"=> array(0,255,0),
"teal"=> array(0,128,128),
"whitesmoke"=>array(245,245,245),
"gainsboro"=>array(220,220,220),
"oldlace"=>array(253,245,230),
"linen"=>array(250,240,230),
"antiquewhite"=>array(250,235,215),
"papayawhip"=>array(255,239,213),
"blanchedalmond"=>array(255,235,205),
"bisque"=>array(255,228,196),
"peachpuff"=>array(255,218,185),
"navajowhite"=>array(255,222,173),
"moccasin"=>array(255,228,181),
"cornsilk"=>array(255,248,220),
"ivory"=>array(255,255,240),
"lemonchiffon"=>array(255,250,205),
"seashell"=>array(255,245,238),
"mintcream"=>array(245,255,250),
"azure"=>array(240,255,255),
"aliceblue"=>array(240,248,255),
"lavender"=>array(230,230,250),
"lavenderblush"=>array(255,240,245),
"mistyrose"=>array(255,228,225),
"white"=>array(255,255,255),
"black"=>array(0,0,0),
"darkslategray"=>array(47,79,79),
"dimgray"=>array(105,105,105),
"slategray"=>array(112,128,144),
"lightslategray"=>array(119,136,153),
"gray"=>array(190,190,190),
"lightgray"=>array(211,211,211),
"midnightblue"=>array(25,25,112),
"navy"=>array(0,0,128),
"cornflowerblue"=>array(100,149,237),
"darkslateblue"=>array(72,61,139),
"slateblue"=>array(106,90,205),
"mediumslateblue"=>array(123,104,238),
"lightslateblue"=>array(132,112,255),
"mediumblue"=>array(0,0,205),
"royalblue"=>array(65,105,225),
"blue"=>array(0,0,255),
"dodgerblue"=>array(30,144,255),
"deepskyblue"=>array(0,191,255),
"skyblue"=>array(135,206,235),
"lightskyblue"=>array(135,206,250),
"steelblue"=>array(70,130,180),
"lightred"=>array(211,167,168),
"lightsteelblue"=>array(176,196,222),
"lightblue"=>array(173,216,230),
"powderblue"=>array(176,224,230),
"paleturquoise"=>array(175,238,238),
"darkturquoise"=>array(0,206,209),
"mediumturquoise"=>array(72,209,204),
"turquoise"=>array(64,224,208),
"cyan"=>array(0,255,255),
"lightcyan"=>array(224,255,255),
"cadetblue"=>array(95,158,160),
"mediumaquamarine"=>array(102,205,170),
"aquamarine"=>array(127,255,212),
"darkgreen"=>array(0,100,0),
"darkolivegreen"=>array(85,107,47),
"darkseagreen"=>array(143,188,143),
"seagreen"=>array(46,139,87),
"mediumseagreen"=>array(60,179,113),
"lightseagreen"=>array(32,178,170),
"palegreen"=>array(152,251,152),
"springgreen"=>array(0,255,127),
"lawngreen"=>array(124,252,0),
"green"=>array(0,255,0),
"chartreuse"=>array(127,255,0),
"mediumspringgreen"=>array(0,250,154),
"greenyellow"=>array(173,255,47),
"limegreen"=>array(50,205,50),
"yellowgreen"=>array(154,205,50),
"forestgreen"=>array(34,139,34),
"olivedrab"=>array(107,142,35),
"darkkhaki"=>array(189,183,107),
"khaki"=>array(240,230,140),
"palegoldenrod"=>array(238,232,170),
"lightgoldenrodyellow"=>array(250,250,210),
"lightyellow"=>array(255,255,200),
"yellow"=>array(255,255,0),
"gold"=>array(255,215,0),
"lightgoldenrod"=>array(238,221,130),
"goldenrod"=>array(218,165,32),
"darkgoldenrod"=>array(184,134,11),
"rosybrown"=>array(188,143,143),
"indianred"=>array(205,92,92),
"saddlebrown"=>array(139,69,19),
"sienna"=>array(160,82,45),
"peru"=>array(205,133,63),
"burlywood"=>array(222,184,135),
"beige"=>array(245,245,220),
"wheat"=>array(245,222,179),
"sandybrown"=>array(244,164,96),
"tan"=>array(210,180,140),
"chocolate"=>array(210,105,30),
"firebrick"=>array(178,34,34),
"brown"=>array(165,42,42),
"darksalmon"=>array(233,150,122),
"salmon"=>array(250,128,114),
"lightsalmon"=>array(255,160,122),
"orange"=>array(255,165,0),
"darkorange"=>array(255,140,0),
"coral"=>array(255,127,80),
"lightcoral"=>array(240,128,128),
"tomato"=>array(255,99,71),
"orangered"=>array(255,69,0),
"red"=>array(255,0,0),
"hotpink"=>array(255,105,180),
"deeppink"=>array(255,20,147),
"pink"=>array(255,192,203),
"lightpink"=>array(255,182,193),
"palevioletred"=>array(219,112,147),
"maroon"=>array(176,48,96),
"mediumvioletred"=>array(199,21,133),
"violetred"=>array(208,32,144),
"magenta"=>array(255,0,255),
"violet"=>array(238,130,238),
"plum"=>array(221,160,221),
"orchid"=>array(218,112,214),
"mediumorchid"=>array(186,85,211),
"darkorchid"=>array(153,50,204),
"darkviolet"=>array(148,0,211),
"blueviolet"=>array(138,43,226),
"purple"=>array(160,32,240),
"mediumpurple"=>array(147,112,219),
"thistle"=>array(216,191,216),
"snow1"=>array(255,250,250),
"snow2"=>array(238,233,233),
"snow3"=>array(205,201,201),
"snow4"=>array(139,137,137),
"seashell1"=>array(255,245,238),
"seashell2"=>array(238,229,222),
"seashell3"=>array(205,197,191),
"seashell4"=>array(139,134,130),
"AntiqueWhite1"=>array(255,239,219),
"AntiqueWhite2"=>array(238,223,204),
"AntiqueWhite3"=>array(205,192,176),
"AntiqueWhite4"=>array(139,131,120),
"bisque1"=>array(255,228,196),
"bisque2"=>array(238,213,183),
"bisque3"=>array(205,183,158),
"bisque4"=>array(139,125,107),
"peachPuff1"=>array(255,218,185),
"peachpuff2"=>array(238,203,173),
"peachpuff3"=>array(205,175,149),
"peachpuff4"=>array(139,119,101),
"navajowhite1"=>array(255,222,173),
"navajowhite2"=>array(238,207,161),
"navajowhite3"=>array(205,179,139),
"navajowhite4"=>array(139,121,94),
"lemonchiffon1"=>array(255,250,205),
"lemonchiffon2"=>array(238,233,191),
"lemonchiffon3"=>array(205,201,165),
"lemonchiffon4"=>array(139,137,112),
"ivory1"=>array(255,255,240),
"ivory2"=>array(238,238,224),
"ivory3"=>array(205,205,193),
"ivory4"=>array(139,139,131),
"honeydew"=>array(193,205,193),
"lavenderblush1"=>array(255,240,245),
"lavenderblush2"=>array(238,224,229),
"lavenderblush3"=>array(205,193,197),
"lavenderblush4"=>array(139,131,134),
"mistyrose1"=>array(255,228,225),
"mistyrose2"=>array(238,213,210),
"mistyrose3"=>array(205,183,181),
"mistyrose4"=>array(139,125,123),
"azure1"=>array(240,255,255),
"azure2"=>array(224,238,238),
"azure3"=>array(193,205,205),
"azure4"=>array(131,139,139),
"slateblue1"=>array(131,111,255),
"slateblue2"=>array(122,103,238),
"slateblue3"=>array(105,89,205),
"slateblue4"=>array(71,60,139),
"royalblue1"=>array(72,118,255),
"royalblue2"=>array(67,110,238),
"royalblue3"=>array(58,95,205),
"royalblue4"=>array(39,64,139),
"dodgerblue1"=>array(30,144,255),
"dodgerblue2"=>array(28,134,238),
"dodgerblue3"=>array(24,116,205),
"dodgerblue4"=>array(16,78,139),
"steelblue1"=>array(99,184,255),
"steelblue2"=>array(92,172,238),
"steelblue3"=>array(79,148,205),
"steelblue4"=>array(54,100,139),
"deepskyblue1"=>array(0,191,255),
"deepskyblue2"=>array(0,178,238),
"deepskyblue3"=>array(0,154,205),
"deepskyblue4"=>array(0,104,139),
"skyblue1"=>array(135,206,255),
"skyblue2"=>array(126,192,238),
"skyblue3"=>array(108,166,205),
"skyblue4"=>array(74,112,139),
"lightskyblue1"=>array(176,226,255),
"lightskyblue2"=>array(164,211,238),
"lightskyblue3"=>array(141,182,205),
"lightskyblue4"=>array(96,123,139),
"slategray1"=>array(198,226,255),
"slategray2"=>array(185,211,238),
"slategray3"=>array(159,182,205),
"slategray4"=>array(108,123,139),
"lightsteelblue1"=>array(202,225,255),
"lightsteelblue2"=>array(188,210,238),
"lightsteelblue3"=>array(162,181,205),
"lightsteelblue4"=>array(110,123,139),
"lightblue1"=>array(191,239,255),
"lightblue2"=>array(178,223,238),
"lightblue3"=>array(154,192,205),
"lightblue4"=>array(104,131,139),
"lightcyan1"=>array(224,255,255),
"lightcyan2"=>array(209,238,238),
"lightcyan3"=>array(180,205,205),
"lightcyan4"=>array(122,139,139),
"paleturquoise1"=>array(187,255,255),
"paleturquoise2"=>array(174,238,238),
"paleturquoise3"=>array(150,205,205),
"paleturquoise4"=>array(102,139,139),
"cadetblue1"=>array(152,245,255),
"cadetblue2"=>array(142,229,238),
"cadetblue3"=>array(122,197,205),
"cadetblue4"=>array(83,134,139),
"turquoise1"=>array(0,245,255),
"turquoise2"=>array(0,229,238),
"turquoise3"=>array(0,197,205),
"turquoise4"=>array(0,134,139),
"cyan1"=>array(0,255,255),
"cyan2"=>array(0,238,238),
"cyan3"=>array(0,205,205),
"cyan4"=>array(0,139,139),
"darkslategray1"=>array(151,255,255),
"darkslategray2"=>array(141,238,238),
"darkslategray3"=>array(121,205,205),
"darkslategray4"=>array(82,139,139),
"aquamarine1"=>array(127,255,212),
"aquamarine2"=>array(118,238,198),
"aquamarine3"=>array(102,205,170),
"aquamarine4"=>array(69,139,116),
"darkseagreen1"=>array(193,255,193),
"darkseagreen2"=>array(180,238,180),
"darkseagreen3"=>array(155,205,155),
"darkseagreen4"=>array(105,139,105),
"seagreen1"=>array(84,255,159),
"seagreen2"=>array(78,238,148),
"seagreen3"=>array(67,205,128),
"seagreen4"=>array(46,139,87),
"palegreen1"=>array(154,255,154),
"palegreen2"=>array(144,238,144),
"palegreen3"=>array(124,205,124),
"palegreen4"=>array(84,139,84),
"springgreen1"=>array(0,255,127),
"springgreen2"=>array(0,238,118),
"springgreen3"=>array(0,205,102),
"springgreen4"=>array(0,139,69),
"chartreuse1"=>array(127,255,0),
"chartreuse2"=>array(118,238,0),
"chartreuse3"=>array(102,205,0),
"chartreuse4"=>array(69,139,0),
"olivedrab1"=>array(192,255,62),
"olivedrab2"=>array(179,238,58),
"olivedrab3"=>array(154,205,50),
"olivedrab4"=>array(105,139,34),
"darkolivegreen1"=>array(202,255,112),
"darkolivegreen2"=>array(188,238,104),
"darkolivegreen3"=>array(162,205,90),
"darkolivegreen4"=>array(110,139,61),
"khaki1"=>array(255,246,143),
"khaki2"=>array(238,230,133),
"khaki3"=>array(205,198,115),
"khaki4"=>array(139,134,78),
"lightgoldenrod1"=>array(255,236,139),
"lightgoldenrod2"=>array(238,220,130),
"lightgoldenrod3"=>array(205,190,112),
"lightgoldenrod4"=>array(139,129,76),
"yellow1"=>array(255,255,0),
"yellow2"=>array(238,238,0),
"yellow3"=>array(205,205,0),
"yellow4"=>array(139,139,0),
"gold1"=>array(255,215,0),
"gold2"=>array(238,201,0),
"gold3"=>array(205,173,0),
"gold4"=>array(139,117,0),
"goldenrod1"=>array(255,193,37),
"goldenrod2"=>array(238,180,34),
"goldenrod3"=>array(205,155,29),
"goldenrod4"=>array(139,105,20),
"darkgoldenrod1"=>array(255,185,15),
"darkgoldenrod2"=>array(238,173,14),
"darkgoldenrod3"=>array(205,149,12),
"darkgoldenrod4"=>array(139,101,8),
"rosybrown1"=>array(255,193,193),
"rosybrown2"=>array(238,180,180),
"rosybrown3"=>array(205,155,155),
"rosybrown4"=>array(139,105,105),
"indianred1"=>array(255,106,106),
"indianred2"=>array(238,99,99),
"indianred3"=>array(205,85,85),
"indianred4"=>array(139,58,58),
"sienna1"=>array(255,130,71),
"sienna2"=>array(238,121,66),
"sienna3"=>array(205,104,57),
"sienna4"=>array(139,71,38),
"burlywood1"=>array(255,211,155),
"burlywood2"=>array(238,197,145),
"burlywood3"=>array(205,170,125),
"burlywood4"=>array(139,115,85),
"wheat1"=>array(255,231,186),
"wheat2"=>array(238,216,174),
"wheat3"=>array(205,186,150),
"wheat4"=>array(139,126,102),
"tan1"=>array(255,165,79),
"tan2"=>array(238,154,73),
"tan3"=>array(205,133,63),
"tan4"=>array(139,90,43),
"chocolate1"=>array(255,127,36),
"chocolate2"=>array(238,118,33),
"chocolate3"=>array(205,102,29),
"chocolate4"=>array(139,69,19),
"firebrick1"=>array(255,48,48),
"firebrick2"=>array(238,44,44),
"firebrick3"=>array(205,38,38),
"firebrick4"=>array(139,26,26),
"brown1"=>array(255,64,64),
"brown2"=>array(238,59,59),
"brown3"=>array(205,51,51),
"brown4"=>array(139,35,35),
"salmon1"=>array(255,140,105),
"salmon2"=>array(238,130,98),
"salmon3"=>array(205,112,84),
"salmon4"=>array(139,76,57),
"lightsalmon1"=>array(255,160,122),
"lightsalmon2"=>array(238,149,114),
"lightsalmon3"=>array(205,129,98),
"lightsalmon4"=>array(139,87,66),
"orange1"=>array(255,165,0),
"orange2"=>array(238,154,0),
"orange3"=>array(205,133,0),
"orange4"=>array(139,90,0),
"darkorange1"=>array(255,127,0),
"darkorange2"=>array(238,118,0),
"darkorange3"=>array(205,102,0),
"darkorange4"=>array(139,69,0),
"coral1"=>array(255,114,86),
"coral2"=>array(238,106,80),
"coral3"=>array(205,91,69),
"coral4"=>array(139,62,47),
"tomato1"=>array(255,99,71),
"tomato2"=>array(238,92,66),
"tomato3"=>array(205,79,57),
"tomato4"=>array(139,54,38),
"orangered1"=>array(255,69,0),
"orangered2"=>array(238,64,0),
"orangered3"=>array(205,55,0),
"orangered4"=>array(139,37,0),
"deeppink1"=>array(255,20,147),
"deeppink2"=>array(238,18,137),
"deeppink3"=>array(205,16,118),
"deeppink4"=>array(139,10,80),
"hotpink1"=>array(255,110,180),
"hotpink2"=>array(238,106,167),
"hotpink3"=>array(205,96,144),
"hotpink4"=>array(139,58,98),
"pink1"=>array(255,181,197),
"pink2"=>array(238,169,184),
"pink3"=>array(205,145,158),
"pink4"=>array(139,99,108),
"lightpink1"=>array(255,174,185),
"lightpink2"=>array(238,162,173),
"lightpink3"=>array(205,140,149),
"lightpink4"=>array(139,95,101),
"palevioletred1"=>array(255,130,171),
"palevioletred2"=>array(238,121,159),
"palevioletred3"=>array(205,104,137),
"palevioletred4"=>array(139,71,93),
"maroon1"=>array(255,52,179),
"maroon2"=>array(238,48,167),
"maroon3"=>array(205,41,144),
"maroon4"=>array(139,28,98),
"violetred1"=>array(255,62,150),
"violetred2"=>array(238,58,140),
"violetred3"=>array(205,50,120),
"violetred4"=>array(139,34,82),
"magenta1"=>array(255,0,255),
"magenta2"=>array(238,0,238),
"magenta3"=>array(205,0,205),
"magenta4"=>array(139,0,139),
"mediumred"=>array(140,34,34),
"orchid1"=>array(255,131,250),
"orchid2"=>array(238,122,233),
"orchid3"=>array(205,105,201),
"orchid4"=>array(139,71,137),
"plum1"=>array(255,187,255),
"plum2"=>array(238,174,238),
"plum3"=>array(205,150,205),
"plum4"=>array(139,102,139),
"mediumorchid1"=>array(224,102,255),
"mediumorchid2"=>array(209,95,238),
"mediumorchid3"=>array(180,82,205),
"mediumorchid4"=>array(122,55,139),
"darkorchid1"=>array(191,62,255),
"darkorchid2"=>array(178,58,238),
"darkorchid3"=>array(154,50,205),
"darkorchid4"=>array(104,34,139),
"purple1"=>array(155,48,255),
"purple2"=>array(145,44,238),
"purple3"=>array(125,38,205),
"purple4"=>array(85,26,139),
"mediumpurple1"=>array(171,130,255),
"mediumpurple2"=>array(159,121,238),
"mediumpurple3"=>array(137,104,205),
"mediumpurple4"=>array(93,71,139),
"thistle1"=>array(255,225,255),
"thistle2"=>array(238,210,238),
"thistle3"=>array(205,181,205),
"thistle4"=>array(139,123,139),
"gray1"=>array(10,10,10),
"gray2"=>array(40,40,30),
"gray3"=>array(70,70,70),
"gray4"=>array(100,100,100),
"gray5"=>array(130,130,130),
"gray6"=>array(160,160,160),
"gray7"=>array(190,190,190),
"gray8"=>array(210,210,210),
"gray9"=>array(240,240,240),
"darkgray"=>array(100,100,100),
"darkblue"=>array(0,0,139),
"darkcyan"=>array(0,139,139),
"darkmagenta"=>array(139,0,139),
"darkred"=>array(139,0,0),
"silver"=>array(192, 192, 192),
"eggplant"=>array(144,176,168),
"lightgreen"=>array(144,238,144));
}
//----------------
// PUBLIC METHODS
// Colors can be specified as either
// 1. #xxxxxx HTML style
// 2. "colorname" as a named color
// 3. array(r,g,b) RGB triple
// This function translates this to a native RGB format and returns an
// RGB triple.
function Color($aColor) {
if (is_string($aColor)) {
// Strip of any alpha factor
$pos = strpos($aColor,'@');
if( $pos === false ) {
$alpha = 0;
}
else {
$pos2 = strpos($aColor,':');
if( $pos2===false )
$pos2 = $pos-1; // Sentinel
if( $pos > $pos2 ) {
$alpha = str_replace(',','.',substr($aColor,$pos+1));
$aColor = substr($aColor,0,$pos);
}
else {
$alpha = substr($aColor,$pos+1,$pos2-$pos-1);
$aColor = substr($aColor,0,$pos).substr($aColor,$pos2);
}
}
 
// Extract potential adjustment figure at end of color
// specification
$pos = strpos($aColor,":");
if( $pos === false ) {
$adj = 1.0;
}
else {
$adj = 0.0 + str_replace(',','.',substr($aColor,$pos+1));
$aColor = substr($aColor,0,$pos);
}
if( $adj < 0 )
JpGraphError::RaiseL(25077);//('Adjustment factor for color must be > 0');
 
if (substr($aColor, 0, 1) == "#") {
$r = hexdec(substr($aColor, 1, 2));
$g = hexdec(substr($aColor, 3, 2));
$b = hexdec(substr($aColor, 5, 2));
} else {
if(!isset($this->rgb_table[$aColor]) )
JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor");
$tmp=$this->rgb_table[$aColor];
$r = $tmp[0];
$g = $tmp[1];
$b = $tmp[2];
}
// Scale adj so that an adj=2 always
// makes the color 100% white (i.e. 255,255,255.
// and adj=1 neutral and adj=0 black.
if( $adj > 1 ) {
$m = ($adj-1.0)*(255-min(255,min($r,min($g,$b))));
return array(min(255,$r+$m), min(255,$g+$m), min(255,$b+$m),$alpha);
}
elseif( $adj < 1 ) {
$m = ($adj-1.0)*max(255,max($r,max($g,$b)));
return array(max(0,$r+$m), max(0,$g+$m), max(0,$b+$m),$alpha);
}
else {
return array($r,$g,$b,$alpha);
}
 
} elseif( is_array($aColor) ) {
if( count($aColor)==3 ) {
$aColor[3]=0;
return $aColor;
}
else
return $aColor;
}
else
JpGraphError::RaiseL(25079,$aColor,count($aColor));//(" Unknown color specification: $aColor , size=".count($aColor));
}
// Compare two colors
// return true if equal
function Equal($aCol1,$aCol2) {
$c1 = $this->Color($aCol1);
$c2 = $this->Color($aCol2);
if( $c1[0]==$c2[0] && $c1[1]==$c2[1] && $c1[2]==$c2[2] )
return true;
else
return false;
}
// Allocate a new color in the current image
// Return new color index, -1 if no more colors could be allocated
function Allocate($aColor,$aAlpha=0.0) {
list ($r, $g, $b, $a) = $this->color($aColor);
// If alpha is specified in the color string then this
// takes precedence over the second argument
if( $a > 0 )
$aAlpha = $a;
if( $aAlpha < 0 || $aAlpha > 1 ) {
JpGraphError::RaiseL(25080);//('Alpha parameter for color must be between 0.0 and 1.0');
}
return imagecolorresolvealpha($this->img, $r, $g, $b, round($aAlpha * 127));
}
} // Class
 
//===================================================
// CLASS Image
// Description: Wrapper class with some goodies to form the
// Interface to low level image drawing routines.
//===================================================
class Image {
var $img_format;
var $expired=true;
var $img=null;
var $left_margin=30,$right_margin=20,$top_margin=20,$bottom_margin=30;
var $plotwidth=0,$plotheight=0;
var $rgb=null;
var $current_color,$current_color_name;
var $lastx=0, $lasty=0;
var $width=0, $height=0;
var $line_weight=1;
var $line_style=1; // Default line style is solid
var $obs_list=array();
var $font_size=12,$font_family=FF_FONT1, $font_style=FS_NORMAL;
var $font_file='';
var $text_halign="left",$text_valign="bottom";
var $ttf=null;
var $use_anti_aliasing=false;
var $quality=null;
var $colorstack=array(),$colorstackidx=0;
var $canvascolor = 'white' ;
var $langconv = null ;
 
//---------------
// CONSTRUCTOR
function Image($aWidth,$aHeight,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) {
$this->CreateImgCanvas($aWidth,$aHeight);
if( $aSetAutoMargin )
$this->SetAutoMargin();
 
if( !$this->SetImgFormat($aFormat) ) {
JpGraphError::RaiseL(25081,$aFormat);//("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]");
}
$this->ttf = new TTF();
$this->langconv = new LanguageConv();
}
 
// Should we use anti-aliasing. Note: This really slows down graphics!
function SetAntiAliasing() {
$this->use_anti_aliasing=true;
}
 
function CreateRawCanvas($aWidth=0,$aHeight=0) {
if( $aWidth <= 1 || $aHeight <= 1 ) {
JpGraphError::RaiseL(25082,$aWidth,$aHeight);//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)");
}
$this->img = @imagecreatetruecolor($aWidth, $aHeight);
if( $this->img < 1 ) {
JpGraphError::RaiseL(25126);
//die("Can't create truecolor image. Check that you really have GD2 library installed.");
}
$this->SetAlphaBlending();
if( $this->rgb != null )
$this->rgb->img = $this->img ;
else
$this->rgb = new RGB($this->img);
}
 
function CloneCanvasH() {
$oldimage = $this->img;
$this->CreateRawCanvas($this->width,$this->height);
imagecopy($this->img,$oldimage,0,0,0,0,$this->width,$this->height);
return $oldimage;
}
function CreateImgCanvas($aWidth=0,$aHeight=0) {
 
$old = array($this->img,$this->width,$this->height);
$aWidth = round($aWidth);
$aHeight = round($aHeight);
 
$this->width=$aWidth;
$this->height=$aHeight;
 
if( $aWidth==0 || $aHeight==0 ) {
// We will set the final size later.
// Note: The size must be specified before any other
// img routines that stroke anything are called.
$this->img = null;
$this->rgb = null;
return $old;
}
$this->CreateRawCanvas($aWidth,$aHeight);
// Set canvas color (will also be the background color for a
// a pallett image
$this->SetColor($this->canvascolor);
$this->FilledRectangle(0,0,$aWidth,$aHeight);
 
return $old ;
}
 
function CopyCanvasH($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY,$aWidth,$aHeight,$aw=-1,$ah=-1) {
if( $aw === -1 ) {
$aw = $aWidth;
$ah = $aHeight;
$f = 'imagecopyresized';
}
else {
$f = 'imagecopyresampled' ;
}
$f($aToHdl,$aFromHdl,
$aToX,$aToY,$aFromX,$aFromY, $aWidth,$aHeight,$aw,$ah);
}
 
function Copy($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1) {
$this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY,
$toWidth,$toHeight,$fromWidth,$fromHeight);
}
 
function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) {
if( $aMix == 100 ) {
$this->CopyCanvasH($this->img,$fromImg,
$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight);
}
else {
if( ($fromWidth != -1 && ($fromWidth != $toWidth)) ||
($fromHeight != -1 && ($fromHeight != $fromHeight)) ) {
// Create a new canvas that will hold the re-scaled original from image
if( $toWidth <= 1 || $toHeight <= 1 ) {
JpGraphError::RaiseL(25083);//('Illegal image size when copying image. Size for copied to image is 1 pixel or less.');
}
$tmpimg = @imagecreatetruecolor($toWidth, $toHeight);
if( $tmpimg < 1 ) {
JpGraphError::RaiseL(25084);//('Failed to create temporary GD canvas. Out of memory ?');
}
$this->CopyCanvasH($tmpimg,$fromImg,0,0,0,0,
$toWidth,$toHeight,$fromWidth,$fromHeight);
$fromImg = $tmpimg;
}
imagecopymerge($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$aMix);
}
}
 
function GetWidth($aImg=null) {
if( $aImg === null )
$aImg = $this->img;
return imagesx($aImg);
}
 
function GetHeight($aImg=null) {
if( $aImg === null )
$aImg = $this->img;
return imagesy($aImg);
}
function CreateFromString($aStr) {
$img = @imagecreatefromstring($aStr);
if( $img === false ) {
JpGraphError::RaiseL(25085);//('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.');
}
return $img;
}
 
function SetCanvasH($aHdl) {
$this->img = $aHdl;
$this->rgb->img = $aHdl;
}
 
function SetCanvasColor($aColor) {
$this->canvascolor = $aColor ;
}
 
function SetAlphaBlending($aFlg=true) {
ImageAlphaBlending($this->img,$aFlg);
}
 
function SetAutoMargin() {
GLOBAL $gJpgBrandTiming;
$min_bm=5;
/*
if( $gJpgBrandTiming )
$min_bm=15;
*/
$lm = min(40,$this->width/7);
$rm = min(20,$this->width/10);
$tm = max(5,$this->height/7);
$bm = max($min_bm,$this->height/7);
$this->SetMargin($lm,$rm,$tm,$bm);
}
 
//---------------
// PUBLIC METHODS
function SetFont($family,$style=FS_NORMAL,$size=10) {
$this->font_family=$family;
$this->font_style=$style;
$this->font_size=$size;
$this->font_file='';
if( ($this->font_family==FF_FONT1 || $this->font_family==FF_FONT2) && $this->font_style==FS_BOLD ){
++$this->font_family;
}
if( $this->font_family > FF_FONT2+1 ) { // A TTF font so get the font file
 
// Check that this PHP has support for TTF fonts
if( !function_exists('imagettfbbox') ) {
JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.');
}
$this->font_file = $this->ttf->File($this->font_family,$this->font_style);
}
}
 
// Get the specific height for a text string
function GetTextHeight($txt="",$angle=0) {
$tmp = split("\n",$txt);
$n = count($tmp);
$m=0;
for($i=0; $i< $n; ++$i)
$m = max($m,strlen($tmp[$i]));
 
if( $this->font_family <= FF_FONT2+1 ) {
if( $angle==0 ) {
$h = imagefontheight($this->font_family);
if( $h === false ) {
JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
}
 
return $n*$h;
}
else {
$w = @imagefontwidth($this->font_family);
if( $w === false ) {
JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
}
 
return $m*$w;
}
}
else {
$bbox = $this->GetTTFBBox($txt,$angle);
return $bbox[1]-$bbox[5];
}
}
// Estimate font height
function GetFontHeight($angle=0) {
$txt = "XOMg";
return $this->GetTextHeight($txt,$angle);
}
// Approximate font width with width of letter "O"
function GetFontWidth($angle=0) {
$txt = 'O';
return $this->GetTextWidth($txt,$angle);
}
// Get actual width of text in absolute pixels
function GetTextWidth($txt,$angle=0) {
 
$tmp = split("\n",$txt);
$n = count($tmp);
if( $this->font_family <= FF_FONT2+1 ) {
 
$m=0;
for($i=0; $i < $n; ++$i) {
$l=strlen($tmp[$i]);
if( $l > $m ) {
$m = $l;
}
}
 
if( $angle==0 ) {
$w = @imagefontwidth($this->font_family);
if( $w === false ) {
JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
}
return $m*$w;
}
else {
// 90 degrees internal so height becomes width
$h = @imagefontheight($this->font_family);
if( $h === false ) {
JpGraphError::RaiseL(25089);//('You have a misconfigured GD font support. The call to imagefontheight() fails.');
}
return $n*$h;
}
}
else {
// For TTF fonts we must walk through a lines and find the
// widest one which we use as the width of the multi-line
// paragraph
$m=0;
for( $i=0; $i < $n; ++$i ) {
$bbox = $this->GetTTFBBox($tmp[$i],$angle);
$mm = $bbox[2] - $bbox[0];
if( $mm > $m )
$m = $mm;
}
return $m;
}
}
// Draw text with a box around it
function StrokeBoxedText($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black",
$shadowcolor=false,$paragraph_align="left",
$xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) {
 
if( !is_numeric($dir) ) {
if( $dir=="h" ) $dir=0;
elseif( $dir=="v" ) $dir=90;
else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]");
}
if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) {
$width=$this->GetTextWidth($txt,$dir) ;
$height=$this->GetTextHeight($txt,$dir) ;
}
else {
$width=$this->GetBBoxWidth($txt,$dir) ;
$height=$this->GetBBoxHeight($txt,$dir) ;
}
 
$height += 2*$ymarg;
$width += 2*$xmarg;
 
if( $this->text_halign=="right" ) $x -= $width;
elseif( $this->text_halign=="center" ) $x -= $width/2;
if( $this->text_valign=="bottom" ) $y -= $height;
elseif( $this->text_valign=="center" ) $y -= $height/2;
$olda = $this->SetAngle(0);
 
if( $shadowcolor ) {
$this->PushColor($shadowcolor);
$this->FilledRoundedRectangle($x-$xmarg+$dropwidth,$y-$ymarg+$dropwidth,
$x+$width+$dropwidth,$y+$height-$ymarg+$dropwidth,
$cornerradius);
$this->PopColor();
$this->PushColor($fcolor);
$this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,
$x+$width,$y+$height-$ymarg,
$cornerradius);
$this->PopColor();
$this->PushColor($bcolor);
$this->RoundedRectangle($x-$xmarg,$y-$ymarg,
$x+$width,$y+$height-$ymarg,$cornerradius);
$this->PopColor();
}
else {
if( $fcolor ) {
$oc=$this->current_color;
$this->SetColor($fcolor);
$this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius);
$this->current_color=$oc;
}
if( $bcolor ) {
$oc=$this->current_color;
$this->SetColor($bcolor);
$this->RoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius);
$this->current_color=$oc;
}
}
$h=$this->text_halign;
$v=$this->text_valign;
$this->SetTextAlign("left","top");
$this->StrokeText($x, $y, $txt, $dir, $paragraph_align);
$bb = array($x-$xmarg,$y+$height-$ymarg,$x+$width,$y+$height-$ymarg,
$x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg);
$this->SetTextAlign($h,$v);
 
$this->SetAngle($olda);
 
return $bb;
}
 
// Set text alignment
function SetTextAlign($halign,$valign="bottom") {
$this->text_halign=$halign;
$this->text_valign=$valign;
}
 
function _StrokeBuiltinFont($x,$y,$txt,$dir=0,$paragraph_align="left",&$aBoundingBox,$aDebug=false) {
 
if( is_numeric($dir) && $dir!=90 && $dir!=0)
JpGraphError::RaiseL(25091);//(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead.");
 
$h=$this->GetTextHeight($txt);
$fh=$this->GetFontHeight();
$w=$this->GetTextWidth($txt);
if( $this->text_halign=="right")
$x -= $dir==0 ? $w : $h;
elseif( $this->text_halign=="center" ) {
// For center we subtract 1 pixel since this makes the middle
// be prefectly in the middle
$x -= $dir==0 ? $w/2-1 : $h/2;
}
if( $this->text_valign=="top" )
$y += $dir==0 ? $h : $w;
elseif( $this->text_valign=="center" )
$y += $dir==0 ? $h/2 : $w/2;
if( $dir==90 ) {
imagestringup($this->img,$this->font_family,$x,$y,$txt,$this->current_color);
$aBoundingBox = array(round($x),round($y),round($x),round($y-$w),round($x+$h),round($y-$w),round($x+$h),round($y));
if( $aDebug ) {
// Draw bounding box
$this->PushColor('green');
$this->Polygon($aBoundingBox,true);
$this->PopColor();
}
}
else {
if( ereg("\n",$txt) ) {
$tmp = split("\n",$txt);
for($i=0; $i < count($tmp); ++$i) {
$w1 = $this->GetTextWidth($tmp[$i]);
if( $paragraph_align=="left" ) {
imagestring($this->img,$this->font_family,$x,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color);
}
elseif( $paragraph_align=="right" ) {
imagestring($this->img,$this->font_family,$x+($w-$w1),
$y-$h+1+$i*$fh,$tmp[$i],$this->current_color);
}
else {
imagestring($this->img,$this->font_family,$x+$w/2-$w1/2,
$y-$h+1+$i*$fh,$tmp[$i],$this->current_color);
}
}
}
else {
//Put the text
imagestring($this->img,$this->font_family,$x,$y-$h+1,$txt,$this->current_color);
}
if( $aDebug ) {
// Draw the bounding rectangle and the bounding box
$p1 = array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y));
// Draw bounding box
$this->PushColor('green');
$this->Polygon($p1,true);
$this->PopColor();
 
}
$aBoundingBox=array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y));
}
}
 
function AddTxtCR($aTxt) {
// If the user has just specified a '\n'
// instead of '\n\t' we have to add '\r' since
// the width will be too muchy otherwise since when
// we print we stroke the individually lines by hand.
$e = explode("\n",$aTxt);
$n = count($e);
for($i=0; $i<$n; ++$i) {
$e[$i]=str_replace("\r","",$e[$i]);
}
return implode("\n\r",$e);
}
 
function GetTTFBBox($aTxt,$aAngle=0) {
$bbox = @ImageTTFBBox($this->font_size,$aAngle,$this->font_file,$aTxt);
if( $bbox === false ) {
JpGraphError::RaiseL(25092,$this->font_file);
//("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library.");
}
return $bbox;
}
 
function GetBBoxTTF($aTxt,$aAngle=0) {
// Normalize the bounding box to become a minimum
// enscribing rectangle
 
$aTxt = $this->AddTxtCR($aTxt);
 
if( !is_readable($this->font_file) ) {
JpGraphError::RaiseL(25093,$this->font_file);
//('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.');
}
$bbox = $this->GetTTFBBox($aTxt,$aAngle);
 
if( $aAngle==0 )
return $bbox;
if( $aAngle >= 0 ) {
if( $aAngle <= 90 ) { //<=0
$bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1],
$bbox[2],$bbox[5],$bbox[6],$bbox[5]);
}
elseif( $aAngle <= 180 ) { //<= 2
$bbox = array($bbox[4],$bbox[7],$bbox[0],$bbox[7],
$bbox[0],$bbox[3],$bbox[4],$bbox[3]);
}
elseif( $aAngle <= 270 ) { //<= 3
$bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5],
$bbox[6],$bbox[1],$bbox[2],$bbox[1]);
}
else {
$bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3],
$bbox[4],$bbox[7],$bbox[0],$bbox[7]);
}
}
elseif( $aAngle < 0 ) {
if( $aAngle <= -270 ) { // <= -3
$bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1],
$bbox[2],$bbox[5],$bbox[6],$bbox[5]);
}
elseif( $aAngle <= -180 ) { // <= -2
$bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3],
$bbox[4],$bbox[7],$bbox[0],$bbox[7]);
}
elseif( $aAngle <= -90 ) { // <= -1
$bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5],
$bbox[6],$bbox[1],$bbox[2],$bbox[1]);
}
else {
$bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3],
$bbox[4],$bbox[7],$bbox[0],$bbox[7]);
}
}
return $bbox;
}
 
function GetBBoxHeight($aTxt,$aAngle=0) {
$box = $this->GetBBoxTTF($aTxt,$aAngle);
return $box[1]-$box[7]+1;
}
 
function GetBBoxWidth($aTxt,$aAngle=0) {
$box = $this->GetBBoxTTF($aTxt,$aAngle);
return $box[2]-$box[0]+1;
}
 
function _StrokeTTF($x,$y,$txt,$dir=0,$paragraph_align="left",&$aBoundingBox,$debug=false) {
 
// Setupo default inter line margin for paragraphs to
// 25% of the font height.
$ConstLineSpacing = 0.25 ;
 
// Remember the anchor point before adjustment
if( $debug ) {
$ox=$x;
$oy=$y;
}
 
if( !ereg("\n",$txt) || ($dir>0 && ereg("\n",$txt)) ) {
// Format a single line
 
$txt = $this->AddTxtCR($txt);
 
$bbox=$this->GetBBoxTTF($txt,$dir);
// Align x,y ot lower left corner of bbox
$x -= $bbox[0];
$y -= $bbox[1];
 
// Note to self: "topanchor" is deprecated after we changed the
// bopunding box stuff.
if( $this->text_halign=="right" || $this->text_halign=="topanchor" )
$x -= $bbox[2]-$bbox[0];
elseif( $this->text_halign=="center" ) $x -= ($bbox[2]-$bbox[0])/2;
if( $this->text_valign=="top" ) $y += abs($bbox[5])+$bbox[1];
elseif( $this->text_valign=="center" ) $y -= ($bbox[5]-$bbox[1])/2;
 
ImageTTFText ($this->img, $this->font_size, $dir, $x, $y,
$this->current_color,$this->font_file,$txt);
 
// Calculate and return the co-ordinates for the bounding box
$box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$txt);
$p1 = array();
 
 
for($i=0; $i < 4; ++$i) {
$p1[] = round($box[$i*2]+$x);
$p1[] = round($box[$i*2+1]+$y);
}
$aBoundingBox = $p1;
 
// Debugging code to highlight the bonding box and bounding rectangle
// For text at 0 degrees the bounding box and bounding rectangle are the
// same
if( $debug ) {
// Draw the bounding rectangle and the bounding box
$box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$txt);
$p = array();
$p1 = array();
for($i=0; $i < 4; ++$i) {
$p[] = $bbox[$i*2]+$x;
$p[] = $bbox[$i*2+1]+$y;
$p1[] = $box[$i*2]+$x;
$p1[] = $box[$i*2+1]+$y;
}
 
// Draw bounding box
$this->PushColor('green');
$this->Polygon($p1,true);
$this->PopColor();
// Draw bounding rectangle
$this->PushColor('darkgreen');
$this->Polygon($p,true);
$this->PopColor();
// Draw a cross at the anchor point
$this->PushColor('red');
$this->Line($ox-15,$oy,$ox+15,$oy);
$this->Line($ox,$oy-15,$ox,$oy+15);
$this->PopColor();
}
}
else {
// Format a text paragraph
$fh=$this->GetFontHeight();
 
// Line margin is 25% of font height
$linemargin=round($fh*$ConstLineSpacing);
$fh += $linemargin;
$w=$this->GetTextWidth($txt);
 
$y -= $linemargin/2;
$tmp = split("\n",$txt);
$nl = count($tmp);
$h = $nl * $fh;
 
if( $this->text_halign=="right")
$x -= $dir==0 ? $w : $h;
elseif( $this->text_halign=="center" ) {
$x -= $dir==0 ? $w/2 : $h/2;
}
if( $this->text_valign=="top" )
$y += $dir==0 ? $h : $w;
elseif( $this->text_valign=="center" )
$y += $dir==0 ? $h/2 : $w/2;
 
// Here comes a tricky bit.
// Since we have to give the position for the string at the
// baseline this means thaht text will move slightly up
// and down depending on any of it's character descend below
// the baseline, for example a 'g'. To adjust the Y-position
// we therefore adjust the text with the baseline Y-offset
// as used for the current font and size. This will keep the
// baseline at a fixed positoned disregarding the actual
// characters in the string.
$standardbox = $this->GetTTFBBox('Gg',$dir);
$yadj = $standardbox[1];
$xadj = $standardbox[0];
$aBoundingBox = array();
for($i=0; $i < $nl; ++$i) {
$wl = $this->GetTextWidth($tmp[$i]);
$bbox = $this->GetTTFBBox($tmp[$i],$dir);
if( $paragraph_align=="left" ) {
$xl = $x;
}
elseif( $paragraph_align=="right" ) {
$xl = $x + ($w-$wl);
}
else {
// Center
$xl = $x + $w/2 - $wl/2 ;
}
 
$xl -= $bbox[0];
$yl = $y - $yadj;
$xl = $xl - $xadj;
ImageTTFText ($this->img, $this->font_size, $dir,
$xl, $yl-($h-$fh)+$fh*$i,
$this->current_color,$this->font_file,$tmp[$i]);
 
if( $debug ) {
// Draw the bounding rectangle around each line
$box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$tmp[$i]);
$p = array();
for($j=0; $j < 4; ++$j) {
$p[] = $bbox[$j*2]+$xl;
$p[] = $bbox[$j*2+1]+$yl-($h-$fh)+$fh*$i;
}
// Draw bounding rectangle
$this->PushColor('darkgreen');
$this->Polygon($p,true);
$this->PopColor();
}
}
 
// Get the bounding box
$bbox = $this->GetBBoxTTF($txt,$dir);
for($j=0; $j < 4; ++$j) {
$bbox[$j*2]+= round($x);
$bbox[$j*2+1]+= round($y - ($h-$fh) - $yadj);
}
$aBoundingBox = $bbox;
 
if( $debug ) {
// Draw a cross at the anchor point
$this->PushColor('red');
$this->Line($ox-25,$oy,$ox+25,$oy);
$this->Line($ox,$oy-25,$ox,$oy+25);
$this->PopColor();
}
 
}
}
function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) {
 
$x = round($x);
$y = round($y);
 
// Do special language encoding
$txt = $this->langconv->Convert($txt,$this->font_family);
 
if( !is_numeric($dir) )
JpGraphError::RaiseL(25094);//(" Direction for text most be given as an angle between 0 and 90.");
if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) {
$this->_StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug);
}
elseif($this->font_family >= _FF_FIRST && $this->font_family <= _FF_LAST) {
$this->_StrokeTTF($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug);
}
else
JpGraphError::RaiseL(25095);//(" Unknown font font family specification. ");
return $boundingbox;
}
function SetMargin($lm,$rm,$tm,$bm) {
$this->left_margin=$lm;
$this->right_margin=$rm;
$this->top_margin=$tm;
$this->bottom_margin=$bm;
$this->plotwidth=$this->width - $this->left_margin-$this->right_margin ;
$this->plotheight=$this->height - $this->top_margin-$this->bottom_margin ;
if( $this->width > 0 && $this->height > 0 ) {
if( $this->plotwidth < 0 || $this->plotheight < 0 )
JpGraphError::raise("Too small plot area. ($lm,$rm,$tm,$bm : $this->plotwidth x $this->plotheight). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.");
}
}
 
function SetTransparent($color) {
imagecolortransparent ($this->img,$this->rgb->allocate($color));
}
function SetColor($color,$aAlpha=0) {
$this->current_color_name = $color;
$this->current_color=$this->rgb->allocate($color,$aAlpha);
if( $this->current_color == -1 ) {
JpGraphError::RaiseL(25096);
//("Can't allocate any more colors.");
}
return $this->current_color;
}
function PushColor($color) {
if( $color != "" ) {
$this->colorstack[$this->colorstackidx]=$this->current_color_name;
$this->colorstack[$this->colorstackidx+1]=$this->current_color;
$this->colorstackidx+=2;
$this->SetColor($color);
}
else {
JpGraphError::RaiseL(25097);//("Color specified as empty string in PushColor().");
}
}
function PopColor() {
if($this->colorstackidx<1)
JpGraphError::RaiseL(25098);//(" Negative Color stack index. Unmatched call to PopColor()");
$this->current_color=$this->colorstack[--$this->colorstackidx];
$this->current_color_name=$this->colorstack[--$this->colorstackidx];
}
function SetLineWeight($weight) {
$this->line_weight = $weight;
}
function SetStartPoint($x,$y) {
$this->lastx=round($x);
$this->lasty=round($y);
}
function Arc($cx,$cy,$w,$h,$s,$e) {
// GD Arc doesn't like negative angles
while( $s < 0) $s += 360;
while( $e < 0) $e += 360;
imagearc($this->img,round($cx),round($cy),round($w),round($h),
$s,$e,$this->current_color);
}
function FilledArc($xc,$yc,$w,$h,$s,$e,$style="") {
 
while( $s < 0 ) $s += 360;
while( $e < 0 ) $e += 360;
if( $style=="" )
$style=IMG_ARC_PIE;
// Workaround for bug in 4.4.7 which will not draw a correct 360
// degree slice with any other angles than 0,360
if( 360-abs($s-$e) < 0.01 ) {
$s = 0;
$e = 360;
}
if( abs($s-$e) > 0.001 ) {
imagefilledarc($this->img,round($xc),round($yc),round($w),round($h),
round($s),round($e),$this->current_color,$style);
}
}
 
function FilledCakeSlice($cx,$cy,$w,$h,$s,$e) {
$this->CakeSlice($cx,$cy,$w,$h,$s,$e,$this->current_color_name);
}
 
function CakeSlice($xc,$yc,$w,$h,$s,$e,$fillcolor="",$arccolor="") {
$s = round($s); $e = round($e);
$w = round($w); $h = round($h);
$xc = round($xc); $yc = round($yc);
 
if( $s==$e ) {
// A full circle. We draw this a plain circle
$this->PushColor($fillcolor);
imagefilledellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color);
$this->PopColor();
$this->PushColor($arccolor);
imageellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color);
$this->Line($xc,$yc,cos($s*M_PI/180)*$w+$xc,$yc+sin($s*M_PI/180)*$h);
$this->PopColor();
}
else {
$this->PushColor($fillcolor);
$this->FilledArc($xc,$yc,2*$w,2*$h,$s,$e);
$this->PopColor();
if( $arccolor != "" ) {
$this->PushColor($arccolor);
// We add 2 pixels to make the Arc() better aligned with the filled arc.
imagefilledarc($this->img,$xc,$yc,2*$w,2*$h,$s,$e,$this->current_color,IMG_ARC_NOFILL | IMG_ARC_EDGED ) ;
 
// Workaround for bug in 4.4.7 which will not draw a correct 360
// degree slice with any other angles than 0,360. Unfortunately we cannot just
// adjust the angles since the interior ar edge is drawn correct but not the surrounding
// circle. This workaround can only be used with perfect circle shaped arcs
if( PHP_VERSION==='4.4.7' && (360-abs($s-$e) < 0.01 && $w==$h) ) {
$this->Circle($xc,$yc,$w);
}
$this->PopColor();
}
}
}
 
function Ellipse($xc,$yc,$w,$h) {
$this->Arc($xc,$yc,$w,$h,0,360);
}
// Breseham circle gives visually better result then using GD
// built in arc(). It takes some more time but gives better
// accuracy.
function BresenhamCircle($xc,$yc,$r) {
$d = 3-2*$r;
$x = 0;
$y = $r;
while($x<=$y) {
$this->Point($xc+$x,$yc+$y);
$this->Point($xc+$x,$yc-$y);
$this->Point($xc-$x,$yc+$y);
$this->Point($xc-$x,$yc-$y);
$this->Point($xc+$y,$yc+$x);
$this->Point($xc+$y,$yc-$x);
$this->Point($xc-$y,$yc+$x);
$this->Point($xc-$y,$yc-$x);
if( $d<0 ) $d += 4*$x+6;
else {
$d += 4*($x-$y)+10;
--$y;
}
++$x;
}
}
function Circle($xc,$yc,$r) {
if( USE_BRESENHAM )
$this->BresenhamCircle($xc,$yc,$r);
else {
 
/*
// Some experimental code snippet to see if we can get a decent
// result doing a trig-circle
// Create an approximated circle with 0.05 rad resolution
$end = 2*M_PI;
$l = $r/10;
if( $l < 3 ) $l=3;
$step_size = 2*M_PI/(2*$r*M_PI/$l);
$pts = array();
$pts[] = $r + $xc;
$pts[] = $yc;
for( $a=$step_size; $a <= $end; $a += $step_size ) {
$pts[] = round($xc + $r*cos($a));
$pts[] = round($yc - $r*sin($a));
}
imagepolygon($this->img,$pts,count($pts)/2,$this->current_color);
*/
 
$this->Arc($xc,$yc,$r*2,$r*2,0,360);
 
// For some reason imageellipse() isn't in GD 2.0.1, PHP 4.1.1
//imageellipse($this->img,$xc,$yc,$r,$r,$this->current_color);
}
}
function FilledCircle($xc,$yc,$r) {
imagefilledellipse($this->img,round($xc),round($yc),2*$r,2*$r,$this->current_color);
}
// Linear Color InterPolation
function lip($f,$t,$p) {
$p = round($p,1);
$r = $f[0] + ($t[0]-$f[0])*$p;
$g = $f[1] + ($t[1]-$f[1])*$p;
$b = $f[2] + ($t[2]-$f[2])*$p;
return array($r,$g,$b);
}
 
// Anti-aliased line.
// Note that this is roughly 8 times slower then a normal line!
function WuLine($x1,$y1,$x2,$y2) {
// Get foreground line color
$lc = imagecolorsforindex($this->img,$this->current_color);
$lc = array($lc["red"],$lc["green"],$lc["blue"]);
 
$dx = $x2-$x1;
$dy = $y2-$y1;
if( abs($dx) > abs($dy) ) {
if( $dx<0 ) {
$dx = -$dx;$dy = -$dy;
$tmp=$x2;$x2=$x1;$x1=$tmp;
$tmp=$y2;$y2=$y1;$y1=$tmp;
}
$x=$x1<<16; $y=$y1<<16;
$yinc = ($dy*65535)/$dx;
$first=true;
while( ($x >> 16) < $x2 ) {
$bc = @imagecolorsforindex($this->img,imagecolorat($this->img,$x>>16,$y>>16));
if( $bc <= 0 ) {
JpGraphError::RaiseL(25100);//('Problem with color palette and your GD setup. Please disable anti-aliasing or use GD2 with true-color. If you have GD2 library installed please make sure that you have set the USE_GD2 constant to true and that truecolor is enabled.');
}
$bc=array($bc["red"],$bc["green"],$bc["blue"]);
$this->SetColor($this->lip($lc,$bc,($y & 0xFFFF)/65535));
imagesetpixel($this->img,$x>>16,$y>>16,$this->current_color);
$this->SetColor($this->lip($lc,$bc,(~$y & 0xFFFF)/65535));
if( !$first )
imagesetpixel($this->img,$x>>16,($y>>16)+1,$this->current_color);
$x += 65536; $y += $yinc;
$first=false;
}
}
else {
if( $dy<0 ) {
$dx = -$dx;$dy = -$dy;
$tmp=$x2;$x2=$x1;$x1=$tmp;
$tmp=$y2;$y2=$y1;$y1=$tmp;
}
$x=$x1<<16; $y=$y1<<16;
$xinc = ($dx*65535)/$dy;
$first = true;
while( ($y >> 16) < $y2 ) {
$bc = @imagecolorsforindex($this->img,imagecolorat($this->img,$x>>16,$y>>16));
if( $bc <= 0 ) {
JpGraphError::RaiseL(25100);//('Problem with color palette and your GD setup. Please disable anti-aliasing or use GD2 with true-color. If you have GD2 library installed please make sure that you have set the USE_GD2 constant to true and truecolor is enabled.');
 
}
 
$bc=array($bc["red"],$bc["green"],$bc["blue"]);
$this->SetColor($this->lip($lc,$bc,($x & 0xFFFF)/65535));
imagesetpixel($this->img,$x>>16,$y>>16,$this->current_color);
$this->SetColor($this->lip($lc,$bc,(~$x & 0xFFFF)/65535));
if( !$first )
imagesetpixel($this->img,($x>>16)+1,$y>>16,$this->current_color);
$y += 65536; $x += $xinc;
$first = false;
}
}
$this->SetColor($lc);
//imagesetpixel($this->img,$x2,$y2,$this->current_color);
//imagesetpixel($this->img,$x1,$y1,$this->current_color);
}
 
// Set line style dashed, dotted etc
function SetLineStyle($s) {
if( is_numeric($s) ) {
if( $s<1 || $s>4 )
JpGraphError::RaiseL(25101,$s);//(" Illegal numeric argument to SetLineStyle(): ($s)");
}
elseif( is_string($s) ) {
if( $s == "solid" ) $s=1;
elseif( $s == "dotted" ) $s=2;
elseif( $s == "dashed" ) $s=3;
elseif( $s == "longdashed" ) $s=4;
else JpGraphError::RaiseL(25102,$s);//(" Illegal string argument to SetLineStyle(): $s");
}
else {
JpGraphError::RaiseL(25103,$s);//(" Illegal argument to SetLineStyle $s");
}
$old = $this->line_style;
$this->line_style=$s;
return $old;
}
// Same as Line but take the line_style into account
function StyleLine($x1,$y1,$x2,$y2) {
switch( $this->line_style ) {
case 1:// Solid
$this->Line($x1,$y1,$x2,$y2);
break;
case 2: // Dotted
$this->DashedLine($x1,$y1,$x2,$y2,1,6);
break;
case 3: // Dashed
$this->DashedLine($x1,$y1,$x2,$y2,2,4);
break;
case 4: // Longdashes
$this->DashedLine($x1,$y1,$x2,$y2,8,6);
break;
default:
JpGraphError::RaiseL(25104,$this->line_style);//(" Unknown line style: $this->line_style ");
break;
}
}
 
function Line($x1,$y1,$x2,$y2) {
 
$x1 = round($x1);
$x2 = round($x2);
$y1 = round($y1);
$y2 = round($y2);
 
if( $this->line_weight==0 ) return;
if( $this->use_anti_aliasing ) {
$dx = $x2-$x1;
$dy = $y2-$y1;
// Vertical, Horizontal or 45 lines don't need anti-aliasing
if( $dx!=0 && $dy!=0 && $dx!=$dy ) {
$this->WuLine($x1,$y1,$x2,$y2);
return;
}
}
if( $this->line_weight==1 ) {
imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color);
}
elseif( $x1==$x2 ) { // Special case for vertical lines
imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color);
$w1=floor($this->line_weight/2);
$w2=floor(($this->line_weight-1)/2);
for($i=1; $i<=$w1; ++$i)
imageline($this->img,$x1+$i,$y1,$x2+$i,$y2,$this->current_color);
for($i=1; $i<=$w2; ++$i)
imageline($this->img,$x1-$i,$y1,$x2-$i,$y2,$this->current_color);
}
elseif( $y1==$y2 ) { // Special case for horizontal lines
imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color);
$w1=floor($this->line_weight/2);
$w2=floor(($this->line_weight-1)/2);
for($i=1; $i<=$w1; ++$i)
imageline($this->img,$x1,$y1+$i,$x2,$y2+$i,$this->current_color);
for($i=1; $i<=$w2; ++$i)
imageline($this->img,$x1,$y1-$i,$x2,$y2-$i,$this->current_color);
}
else { // General case with a line at an angle
$a = atan2($y1-$y2,$x2-$x1);
// Now establish some offsets from the center. This gets a little
// bit involved since we are dealing with integer functions and we
// want the apperance to be as smooth as possible and never be thicker
// then the specified width.
// We do the trig stuff to make sure that the endpoints of the line
// are perpendicular to the line itself.
$dx=(sin($a)*$this->line_weight/2);
$dy=(cos($a)*$this->line_weight/2);
 
$pnts = array(round($x2+$dx),round($y2+$dy),round($x2-$dx),round($y2-$dy),
round($x1-$dx),round($y1-$dy),round($x1+$dx),round($y1+$dy));
imagefilledpolygon($this->img,$pnts,count($pnts)/2,$this->current_color);
}
$this->lastx=$x2; $this->lasty=$y2;
}
 
function Polygon($p,$closed=FALSE,$fast=FALSE) {
if( $this->line_weight==0 ) return;
$n=count($p);
$oldx = $p[0];
$oldy = $p[1];
if( $fast ) {
for( $i=2; $i < $n; $i+=2 ) {
imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->current_color);
$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->current_color);
}
}
else {
for( $i=2; $i < $n; $i+=2 ) {
$this->StyleLine($oldx,$oldy,$p[$i],$p[$i+1]);
$oldx = $p[$i];
$oldy = $p[$i+1];
}
if( $closed )
$this->Line($oldx,$oldy,$p[0],$p[1]);
}
}
function FilledPolygon($pts) {
$n=count($pts);
if( $n == 0 ) {
JpGraphError::RaiseL(25105);//('NULL data specified for a filled polygon. Check that your data is not NULL.');
}
for($i=0; $i < $n; ++$i)
$pts[$i] = round($pts[$i]);
imagefilledpolygon($this->img,$pts,count($pts)/2,$this->current_color);
}
function Rectangle($xl,$yu,$xr,$yl) {
$this->Polygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl,$xl,$yu));
}
function FilledRectangle($xl,$yu,$xr,$yl) {
$this->FilledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl));
}
 
function FilledRectangle2($xl,$yu,$xr,$yl,$color1,$color2,$style=1) {
// Fill a rectangle with lines of two colors
if( $style===1 ) {
// Horizontal stripe
if( $yl < $yu ) {
$t = $yl; $yl=$yu; $yu=$t;
}
for( $y=$yu; $y <= $yl; ++$y) {
$this->SetColor($color1);
$this->Line($xl,$y,$xr,$y);
++$y;
$this->SetColor($color2);
$this->Line($xl,$y,$xr,$y);
}
}
else {
if( $xl < $xl ) {
$t = $xl; $xl=$xr; $xr=$t;
}
for( $x=$xl; $x <= $xr; ++$x) {
$this->SetColor($color1);
$this->Line($x,$yu,$x,$yl);
++$x;
$this->SetColor($color2);
$this->Line($x,$yu,$x,$yl);
}
}
}
 
function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width=3,$shadow_color=array(102,102,102)) {
// This is complicated by the fact that we must also handle the case where
// the reactangle has no fill color
$this->PushColor($shadow_color);
$this->FilledRectangle($xr-$shadow_width,$yu+$shadow_width,$xr,$yl-$shadow_width-1);
$this->FilledRectangle($xl+$shadow_width,$yl-$shadow_width,$xr,$yl);
//$this->FilledRectangle($xl+$shadow_width,$yu+$shadow_width,$xr,$yl);
$this->PopColor();
if( $fcolor==false )
$this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1);
else {
$this->PushColor($fcolor);
$this->FilledRectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1);
$this->PopColor();
$this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1);
}
}
 
function FilledRoundedRectangle($xt,$yt,$xr,$yl,$r=5) {
if( $r==0 ) {
$this->FilledRectangle($xt,$yt,$xr,$yl);
return;
}
 
// To avoid overlapping fillings (which will look strange
// when alphablending is enabled) we have no choice but
// to fill the five distinct areas one by one.
// Center square
$this->FilledRectangle($xt+$r,$yt+$r,$xr-$r,$yl-$r);
// Top band
$this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r-1);
// Bottom band
$this->FilledRectangle($xt+$r,$yl-$r+1,$xr-$r,$yl);
// Left band
$this->FilledRectangle($xt,$yt+$r+1,$xt+$r-1,$yl-$r);
// Right band
$this->FilledRectangle($xr-$r+1,$yt+$r,$xr,$yl-$r);
 
// Topleft & Topright arc
$this->FilledArc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
$this->FilledArc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
 
// Bottomleft & Bottom right arc
$this->FilledArc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
$this->FilledArc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
 
}
 
function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) {
 
if( $r==0 ) {
$this->Rectangle($xt,$yt,$xr,$yl);
return;
}
 
// Top & Bottom line
$this->Line($xt+$r,$yt,$xr-$r,$yt);
$this->Line($xt+$r,$yl,$xr-$r,$yl);
 
// Left & Right line
$this->Line($xt,$yt+$r,$xt,$yl-$r);
$this->Line($xr,$yt+$r,$xr,$yl-$r);
 
// Topleft & Topright arc
$this->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
$this->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
 
// Bottomleft & Bottomright arc
$this->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
$this->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
}
 
function FilledBevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='darkgray@0.4') {
$this->FilledRectangle($x1,$y1,$x2,$y2);
$this->Bevel($x1,$y1,$x2,$y2,$depth,$color1,$color2);
}
 
function Bevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='black@0.5') {
$this->PushColor($color1);
for( $i=0; $i < $depth; ++$i ) {
$this->Line($x1+$i,$y1+$i,$x1+$i,$y2-$i);
$this->Line($x1+$i,$y1+$i,$x2-$i,$y1+$i);
}
$this->PopColor();
$this->PushColor($color2);
for( $i=0; $i < $depth; ++$i ) {
$this->Line($x1+$i,$y2-$i,$x2-$i,$y2-$i);
$this->Line($x2-$i,$y1+$i,$x2-$i,$y2-$i-1);
}
$this->PopColor();
}
 
function StyleLineTo($x,$y) {
$this->StyleLine($this->lastx,$this->lasty,$x,$y);
$this->lastx=$x;
$this->lasty=$y;
}
function LineTo($x,$y) {
$this->Line($this->lastx,$this->lasty,$x,$y);
$this->lastx=$x;
$this->lasty=$y;
}
function Point($x,$y) {
imagesetpixel($this->img,round($x),round($y),$this->current_color);
}
function Fill($x,$y) {
imagefill($this->img,round($x),round($y),$this->current_color);
}
 
function FillToBorder($x,$y,$aBordColor) {
$bc = $this->rgb->allocate($aBordColor);
if( $bc == -1 ) {
JpGraphError::RaiseL(25106);//('Image::FillToBorder : Can not allocate more colors');
}
imagefilltoborder($this->img,round($x),round($y),$bc,$this->current_color);
}
function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) {
 
$x1 = round($x1);
$x2 = round($x2);
$y1 = round($y1);
$y2 = round($y2);
 
// Code based on, but not identical to, work by Ariel Garza and James Pine
$line_length = ceil (sqrt(pow(($x2 - $x1),2) + pow(($y2 - $y1),2)) );
$dx = ($line_length) ? ($x2 - $x1) / $line_length : 0;
$dy = ($line_length) ? ($y2 - $y1) / $line_length : 0;
$lastx = $x1; $lasty = $y1;
$xmax = max($x1,$x2);
$xmin = min($x1,$x2);
$ymax = max($y1,$y2);
$ymin = min($y1,$y2);
for ($i = 0; $i < $line_length; $i += ($dash_length + $dash_space)) {
$x = ($dash_length * $dx) + $lastx;
$y = ($dash_length * $dy) + $lasty;
// The last section might overshoot so we must take a computational hit
// and check this.
if( $x>$xmax ) $x=$xmax;
if( $y>$ymax ) $y=$ymax;
if( $x<$xmin ) $x=$xmin;
if( $y<$ymin ) $y=$ymin;
 
$this->Line($lastx,$lasty,$x,$y);
$lastx = $x + ($dash_space * $dx);
$lasty = $y + ($dash_space * $dy);
}
}
 
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;
 
// These parameters are set by headers_sent() but they might cause
// an undefined variable error unless they are initilized
$file='';
$lineno='';
if( headers_sent($file,$lineno) ) {
$file=basename($file);
$t = new ErrMsgText();
$msg = $t->Get(10,$file,$lineno);
die($msg);
}
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");
}
 
// Adjust image quality for formats that allow this
function SetQuality($q) {
$this->quality = $q;
}
// Stream image to browser or to file
function Stream($aFile="") {
$func="image".$this->img_format;
if( $this->img_format=="jpeg" && $this->quality != null ) {
$res = @$func($this->img,$aFile,$this->quality);
}
else {
if( $aFile != "" ) {
$res = @$func($this->img,$aFile);
if( !$res )
JpGraphError::RaiseL(25107,$aFile);//("Can't write to file '$aFile'. Check that the process running PHP has enough permission.");
}
else {
$res = @$func($this->img);
if( !$res )
JpGraphError::RaiseL(25108);//("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP.");
}
}
}
// Clear resource tide up by image
function Destroy() {
imagedestroy($this->img);
}
// Specify image format. Note depending on your installation
// of PHP not all formats may be supported.
function SetImgFormat($aFormat,$aQuality=75) {
$this->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";
elseif( $supported & IMG_WBMP )
$this->img_format="wbmp";
elseif( $supported & IMG_XPM )
$this->img_format="xpm";
else
JpGraphError::RaiseL(25109);//("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" || $aFormat=="wbmp" || $aFormat=="xpm") {
if( $aFormat=="jpeg" && !($supported & IMG_JPG) )
$tst=false;
elseif( $aFormat=="png" && !($supported & IMG_PNG) )
$tst=false;
elseif( $aFormat=="gif" && !($supported & IMG_GIF) )
$tst=false;
elseif( $aFormat=="wbmp" && !($supported & IMG_WBMP) )
$tst=false;
elseif( $aFormat=="xpm" && !($supported & IMG_XPM) )
$tst=false;
else {
$this->img_format=$aFormat;
return true;
}
}
else
$tst=false;
if( !$tst )
JpGraphError::RaiseL(25110,$aFormat);//(" Your PHP installation does not support the chosen graphic format: $aFormat");
}
}
} // CLASS
 
//===================================================
// CLASS RotImage
// Description: Exactly as Image but draws the image at
// a specified angle around a specified rotation point.
//===================================================
class RotImage extends Image {
var $m=array();
var $a=0;
var $dx=0,$dy=0,$transx=0,$transy=0;
function RotImage($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) {
$this->Image($aWidth,$aHeight,$aFormat,$aSetAutoMargin);
$this->dx=$this->left_margin+$this->plotwidth/2;
$this->dy=$this->top_margin+$this->plotheight/2;
$this->SetAngle($a);
}
function SetCenter($dx,$dy) {
$old_dx = $this->dx;
$old_dy = $this->dy;
$this->dx=$dx;
$this->dy=$dy;
$this->SetAngle($this->a);
return array($old_dx,$old_dy);
}
function SetTranslation($dx,$dy) {
$old = array($this->transx,$this->transy);
$this->transx = $dx;
$this->transy = $dy;
return $old;
}
 
function UpdateRotMatrice() {
$a = $this->a;
$a *= M_PI/180;
$sa=sin($a); $ca=cos($a);
// Create the rotation matrix
$this->m[0][0] = $ca;
$this->m[0][1] = -$sa;
$this->m[0][2] = $this->dx*(1-$ca) + $sa*$this->dy ;
$this->m[1][0] = $sa;
$this->m[1][1] = $ca;
$this->m[1][2] = $this->dy*(1-$ca) - $sa*$this->dx ;
}
 
function SetAngle($a) {
$tmp = $this->a;
$this->a = $a;
$this->UpdateRotMatrice();
return $tmp;
}
 
function Circle($xc,$yc,$r) {
// Circle get's rotated through the Arc() call
// made in the parent class
parent::Circle($xc,$yc,$r);
}
 
function FilledCircle($xc,$yc,$r) {
list($xc,$yc) = $this->Rotate($xc,$yc);
parent::FilledCircle($xc,$yc,$r);
}
function Arc($xc,$yc,$w,$h,$s,$e) {
list($xc,$yc) = $this->Rotate($xc,$yc);
$s += $this->a;
$e += $this->a;
parent::Arc($xc,$yc,$w,$h,$s,$e);
}
 
function FilledArc($xc,$yc,$w,$h,$s,$e) {
list($xc,$yc) = $this->Rotate($xc,$yc);
$s += $this->a;
$e += $this->a;
parent::FilledArc($xc,$yc,$w,$h,$s,$e);
}
 
function SetMargin($lm,$rm,$tm,$bm) {
parent::SetMargin($lm,$rm,$tm,$bm);
$this->dx=$this->left_margin+$this->plotwidth/2;
$this->dy=$this->top_margin+$this->plotheight/2;
$this->UpdateRotMatrice();
}
function Rotate($x,$y) {
// Optimization. Ignore rotation if Angle==0 || ANgle==360
if( $this->a == 0 || $this->a == 360 ) {
return array($x + $this->transx, $y + $this->transy );
}
else {
$x1=round($this->m[0][0]*$x + $this->m[0][1]*$y,1) + $this->m[0][2] + $this->transx;
$y1=round($this->m[1][0]*$x + $this->m[1][1]*$y,1) + $this->m[1][2] + $this->transy;
return array($x1,$y1);
}
}
 
function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) {
list($toX,$toY) = $this->Rotate($toX,$toY);
parent::CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight,$aMix);
 
}
function ArrRotate($pnts) {
$n = count($pnts)-1;
for($i=0; $i < $n; $i+=2) {
list ($x,$y) = $this->Rotate($pnts[$i],$pnts[$i+1]);
$pnts[$i] = $x; $pnts[$i+1] = $y;
}
return $pnts;
}
function Line($x1,$y1,$x2,$y2) {
list($x1,$y1) = $this->Rotate($x1,$y1);
list($x2,$y2) = $this->Rotate($x2,$y2);
parent::Line($x1,$y1,$x2,$y2);
}
 
function Rectangle($x1,$y1,$x2,$y2) {
// Rectangle uses Line() so it will be rotated through that call
parent::Rectangle($x1,$y1,$x2,$y2);
}
function FilledRectangle($x1,$y1,$x2,$y2) {
if( $y1==$y2 || $x1==$x2 )
$this->Line($x1,$y1,$x2,$y2);
else
$this->FilledPolygon(array($x1,$y1,$x2,$y1,$x2,$y2,$x1,$y2));
}
function Polygon($pnts,$closed=FALSE,$fast=false) {
// Polygon uses Line() so it will be rotated through that call unless
// fast drawing routines are used in which case a rotate is needed
if( $fast ) {
parent::Polygon($this->ArrRotate($pnts));
}
else
parent::Polygon($pnts,$closed,$fast);
}
function FilledPolygon($pnts) {
parent::FilledPolygon($this->ArrRotate($pnts));
}
function Point($x,$y) {
list($xp,$yp) = $this->Rotate($x,$y);
parent::Point($xp,$yp);
}
function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) {
list($xp,$yp) = $this->Rotate($x,$y);
return parent::StrokeText($xp,$yp,$txt,$dir,$paragraph_align,$debug);
}
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb100x100.dat
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/flags_thumb100x100.dat
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_flags.php
New file
0,0 → 1,376
<?php
//=======================================================================
// File: JPGRAPH_FLAGS.PHP
// Description: Class Jpfile. Handles plotmarks
// Created: 2003-06-28
// Ver: $Id: jpgraph_flags.php 926 2007-10-13 18:22:39Z 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 {
 
var $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',
'Bangladesh' => 'bngl',
'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',
'Romania' => 'rmna',
'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 Serbia' => 'serb',
'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' ) ;
 
 
var $iFlagCount = -1;
var $iFlagSetMap = array(
FLAGSIZE1 => 'flags_thumb35x35',
FLAGSIZE2 => 'flags_thumb60x60',
FLAGSIZE3 => 'flags_thumb100x100',
FLAGSIZE4 => 'flags'
);
 
var $iFlagData ;
var $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\".");
}
}
}
 
 
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_antispam-digits.php
New file
0,0 → 1,204
<?php
//=======================================================================
// File: JPGRAPH_ANTISPAM.PHP
// Description: Genarate anti-spam challenge
// Created: 2004-10-07
// Ver: $Id: jpgraph_antispam-digits.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class HandDigits {
var $digits_thumb30x30 = array();
var $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;
}
}
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_gb2312.php
New file
0,0 → 1,1552
<?php
//=======================================================================
// File: JPGRAPH_GB2312.PHP
// Description: PHP4 Graph Plotting library. Chinese font conversions
// Created: 2003-05-30
// Ver: $Id: jpgraph_gb2312.php 782 2006-10-08 08:09:02Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
 
class GB2312toUTF8 {
// --------------------------------------------------------------------
// This code table is used to translate GB2312 code (key) to
// it's corresponding Unicode value (data)
// --------------------------------------------------------------------
var $codetable = array(
8481 => 12288, 8482 => 12289, 8483 => 12290, 8484 => 12539, 8485 => 713,
8486 => 711, 8487 => 168, 8488 => 12291, 8489 => 12293, 8490 => 8213,
8491 => 65374, 8492 => 8214, 8493 => 8230, 8494 => 8216, 8495 => 8217,
8496 => 8220, 8497 => 8221, 8498 => 12308, 8499 => 12309, 8500 => 12296,
8501 => 12297, 8502 => 12298, 8503 => 12299, 8504 => 12300, 8505 => 12301,
8506 => 12302, 8507 => 12303, 8508 => 12310, 8509 => 12311, 8510 => 12304,
8511 => 12305, 8512 => 177, 8513 => 215, 8514 => 247, 8515 => 8758,
8516 => 8743, 8517 => 8744, 8518 => 8721, 8519 => 8719, 8520 => 8746,
8521 => 8745, 8522 => 8712, 8523 => 8759, 8524 => 8730, 8525 => 8869,
8526 => 8741, 8527 => 8736, 8528 => 8978, 8529 => 8857, 8530 => 8747,
8531 => 8750, 8532 => 8801, 8533 => 8780, 8534 => 8776, 8535 => 8765,
8536 => 8733, 8537 => 8800, 8538 => 8814, 8539 => 8815, 8540 => 8804,
8541 => 8805, 8542 => 8734, 8543 => 8757, 8544 => 8756, 8545 => 9794,
8546 => 9792, 8547 => 176, 8548 => 8242, 8549 => 8243, 8550 => 8451,
8551 => 65284, 8552 => 164, 8553 => 65504, 8554 => 65505, 8555 => 8240,
8556 => 167, 8557 => 8470, 8558 => 9734, 8559 => 9733, 8560 => 9675,
8561 => 9679, 8562 => 9678, 8563 => 9671, 8564 => 9670, 8565 => 9633,
8566 => 9632, 8567 => 9651, 8568 => 9650, 8569 => 8251, 8570 => 8594,
8571 => 8592, 8572 => 8593, 8573 => 8595, 8574 => 12307, 8753 => 9352,
8754 => 9353, 8755 => 9354, 8756 => 9355, 8757 => 9356, 8758 => 9357,
8759 => 9358, 8760 => 9359, 8761 => 9360, 8762 => 9361, 8763 => 9362,
8764 => 9363, 8765 => 9364, 8766 => 9365, 8767 => 9366, 8768 => 9367,
8769 => 9368, 8770 => 9369, 8771 => 9370, 8772 => 9371, 8773 => 9332,
8774 => 9333, 8775 => 9334, 8776 => 9335, 8777 => 9336, 8778 => 9337,
8779 => 9338, 8780 => 9339, 8781 => 9340, 8782 => 9341, 8783 => 9342,
8784 => 9343, 8785 => 9344, 8786 => 9345, 8787 => 9346, 8788 => 9347,
8789 => 9348, 8790 => 9349, 8791 => 9350, 8792 => 9351, 8793 => 9312,
8794 => 9313, 8795 => 9314, 8796 => 9315, 8797 => 9316, 8798 => 9317,
8799 => 9318, 8800 => 9319, 8801 => 9320, 8802 => 9321, 8805 => 12832,
8806 => 12833, 8807 => 12834, 8808 => 12835, 8809 => 12836, 8810 => 12837,
8811 => 12838, 8812 => 12839, 8813 => 12840, 8814 => 12841, 8817 => 8544,
8818 => 8545, 8819 => 8546, 8820 => 8547, 8821 => 8548, 8822 => 8549,
8823 => 8550, 8824 => 8551, 8825 => 8552, 8826 => 8553, 8827 => 8554,
8828 => 8555, 8993 => 65281, 8994 => 65282, 8995 => 65283, 8996 => 65509,
8997 => 65285, 8998 => 65286, 8999 => 65287, 9000 => 65288, 9001 => 65289,
9002 => 65290, 9003 => 65291, 9004 => 65292, 9005 => 65293, 9006 => 65294,
9007 => 65295, 9008 => 65296, 9009 => 65297, 9010 => 65298, 9011 => 65299,
9012 => 65300, 9013 => 65301, 9014 => 65302, 9015 => 65303, 9016 => 65304,
9017 => 65305, 9018 => 65306, 9019 => 65307, 9020 => 65308, 9021 => 65309,
9022 => 65310, 9023 => 65311, 9024 => 65312, 9025 => 65313, 9026 => 65314,
9027 => 65315, 9028 => 65316, 9029 => 65317, 9030 => 65318, 9031 => 65319,
9032 => 65320, 9033 => 65321, 9034 => 65322, 9035 => 65323, 9036 => 65324,
9037 => 65325, 9038 => 65326, 9039 => 65327, 9040 => 65328, 9041 => 65329,
9042 => 65330, 9043 => 65331, 9044 => 65332, 9045 => 65333, 9046 => 65334,
9047 => 65335, 9048 => 65336, 9049 => 65337, 9050 => 65338, 9051 => 65339,
9052 => 65340, 9053 => 65341, 9054 => 65342, 9055 => 65343, 9056 => 65344,
9057 => 65345, 9058 => 65346, 9059 => 65347, 9060 => 65348, 9061 => 65349,
9062 => 65350, 9063 => 65351, 9064 => 65352, 9065 => 65353, 9066 => 65354,
9067 => 65355, 9068 => 65356, 9069 => 65357, 9070 => 65358, 9071 => 65359,
9072 => 65360, 9073 => 65361, 9074 => 65362, 9075 => 65363, 9076 => 65364,
9077 => 65365, 9078 => 65366, 9079 => 65367, 9080 => 65368, 9081 => 65369,
9082 => 65370, 9083 => 65371, 9084 => 65372, 9085 => 65373, 9086 => 65507,
9249 => 12353, 9250 => 12354, 9251 => 12355, 9252 => 12356, 9253 => 12357,
9254 => 12358, 9255 => 12359, 9256 => 12360, 9257 => 12361, 9258 => 12362,
9259 => 12363, 9260 => 12364, 9261 => 12365, 9262 => 12366, 9263 => 12367,
9264 => 12368, 9265 => 12369, 9266 => 12370, 9267 => 12371, 9268 => 12372,
9269 => 12373, 9270 => 12374, 9271 => 12375, 9272 => 12376, 9273 => 12377,
9274 => 12378, 9275 => 12379, 9276 => 12380, 9277 => 12381, 9278 => 12382,
9279 => 12383, 9280 => 12384, 9281 => 12385, 9282 => 12386, 9283 => 12387,
9284 => 12388, 9285 => 12389, 9286 => 12390, 9287 => 12391, 9288 => 12392,
9289 => 12393, 9290 => 12394, 9291 => 12395, 9292 => 12396, 9293 => 12397,
9294 => 12398, 9295 => 12399, 9296 => 12400, 9297 => 12401, 9298 => 12402,
9299 => 12403, 9300 => 12404, 9301 => 12405, 9302 => 12406, 9303 => 12407,
9304 => 12408, 9305 => 12409, 9306 => 12410, 9307 => 12411, 9308 => 12412,
9309 => 12413, 9310 => 12414, 9311 => 12415, 9312 => 12416, 9313 => 12417,
9314 => 12418, 9315 => 12419, 9316 => 12420, 9317 => 12421, 9318 => 12422,
9319 => 12423, 9320 => 12424, 9321 => 12425, 9322 => 12426, 9323 => 12427,
9324 => 12428, 9325 => 12429, 9326 => 12430, 9327 => 12431, 9328 => 12432,
9329 => 12433, 9330 => 12434, 9331 => 12435, 9505 => 12449, 9506 => 12450,
9507 => 12451, 9508 => 12452, 9509 => 12453, 9510 => 12454, 9511 => 12455,
9512 => 12456, 9513 => 12457, 9514 => 12458, 9515 => 12459, 9516 => 12460,
9517 => 12461, 9518 => 12462, 9519 => 12463, 9520 => 12464, 9521 => 12465,
9522 => 12466, 9523 => 12467, 9524 => 12468, 9525 => 12469, 9526 => 12470,
9527 => 12471, 9528 => 12472, 9529 => 12473, 9530 => 12474, 9531 => 12475,
9532 => 12476, 9533 => 12477, 9534 => 12478, 9535 => 12479, 9536 => 12480,
9537 => 12481, 9538 => 12482, 9539 => 12483, 9540 => 12484, 9541 => 12485,
9542 => 12486, 9543 => 12487, 9544 => 12488, 9545 => 12489, 9546 => 12490,
9547 => 12491, 9548 => 12492, 9549 => 12493, 9550 => 12494, 9551 => 12495,
9552 => 12496, 9553 => 12497, 9554 => 12498, 9555 => 12499, 9556 => 12500,
9557 => 12501, 9558 => 12502, 9559 => 12503, 9560 => 12504, 9561 => 12505,
9562 => 12506, 9563 => 12507, 9564 => 12508, 9565 => 12509, 9566 => 12510,
9567 => 12511, 9568 => 12512, 9569 => 12513, 9570 => 12514, 9571 => 12515,
9572 => 12516, 9573 => 12517, 9574 => 12518, 9575 => 12519, 9576 => 12520,
9577 => 12521, 9578 => 12522, 9579 => 12523, 9580 => 12524, 9581 => 12525,
9582 => 12526, 9583 => 12527, 9584 => 12528, 9585 => 12529, 9586 => 12530,
9587 => 12531, 9588 => 12532, 9589 => 12533, 9590 => 12534, 9761 => 913,
9762 => 914, 9763 => 915, 9764 => 916, 9765 => 917, 9766 => 918,
9767 => 919, 9768 => 920, 9769 => 921, 9770 => 922, 9771 => 923,
9772 => 924, 9773 => 925, 9774 => 926, 9775 => 927, 9776 => 928,
9777 => 929, 9778 => 931, 9779 => 932, 9780 => 933, 9781 => 934,
9782 => 935, 9783 => 936, 9784 => 937, 9793 => 945, 9794 => 946,
9795 => 947, 9796 => 948, 9797 => 949, 9798 => 950, 9799 => 951,
9800 => 952, 9801 => 953, 9802 => 954, 9803 => 955, 9804 => 956,
9805 => 957, 9806 => 958, 9807 => 959, 9808 => 960, 9809 => 961,
9810 => 963, 9811 => 964, 9812 => 965, 9813 => 966, 9814 => 967,
9815 => 968, 9816 => 969, 10017 => 1040, 10018 => 1041, 10019 => 1042,
10020 => 1043, 10021 => 1044, 10022 => 1045, 10023 => 1025, 10024 => 1046,
10025 => 1047, 10026 => 1048, 10027 => 1049, 10028 => 1050, 10029 => 1051,
10030 => 1052, 10031 => 1053, 10032 => 1054, 10033 => 1055, 10034 => 1056,
10035 => 1057, 10036 => 1058, 10037 => 1059, 10038 => 1060, 10039 => 1061,
10040 => 1062, 10041 => 1063, 10042 => 1064, 10043 => 1065, 10044 => 1066,
10045 => 1067, 10046 => 1068, 10047 => 1069, 10048 => 1070, 10049 => 1071,
10065 => 1072, 10066 => 1073, 10067 => 1074, 10068 => 1075, 10069 => 1076,
10070 => 1077, 10071 => 1105, 10072 => 1078, 10073 => 1079, 10074 => 1080,
10075 => 1081, 10076 => 1082, 10077 => 1083, 10078 => 1084, 10079 => 1085,
10080 => 1086, 10081 => 1087, 10082 => 1088, 10083 => 1089, 10084 => 1090,
10085 => 1091, 10086 => 1092, 10087 => 1093, 10088 => 1094, 10089 => 1095,
10090 => 1096, 10091 => 1097, 10092 => 1098, 10093 => 1099, 10094 => 1100,
10095 => 1101, 10096 => 1102, 10097 => 1103, 10273 => 257, 10274 => 225,
10275 => 462, 10276 => 224, 10277 => 275, 10278 => 233, 10279 => 283,
10280 => 232, 10281 => 299, 10282 => 237, 10283 => 464, 10284 => 236,
10285 => 333, 10286 => 243, 10287 => 466, 10288 => 242, 10289 => 363,
10290 => 250, 10291 => 468, 10292 => 249, 10293 => 470, 10294 => 472,
10295 => 474, 10296 => 476, 10297 => 252, 10298 => 234, 10309 => 12549,
10310 => 12550, 10311 => 12551, 10312 => 12552, 10313 => 12553, 10314 => 12554,
10315 => 12555, 10316 => 12556, 10317 => 12557, 10318 => 12558, 10319 => 12559,
10320 => 12560, 10321 => 12561, 10322 => 12562, 10323 => 12563, 10324 => 12564,
10325 => 12565, 10326 => 12566, 10327 => 12567, 10328 => 12568, 10329 => 12569,
10330 => 12570, 10331 => 12571, 10332 => 12572, 10333 => 12573, 10334 => 12574,
10335 => 12575, 10336 => 12576, 10337 => 12577, 10338 => 12578, 10339 => 12579,
10340 => 12580, 10341 => 12581, 10342 => 12582, 10343 => 12583, 10344 => 12584,
10345 => 12585, 10532 => 9472, 10533 => 9473, 10534 => 9474, 10535 => 9475,
10536 => 9476, 10537 => 9477, 10538 => 9478, 10539 => 9479, 10540 => 9480,
10541 => 9481, 10542 => 9482, 10543 => 9483, 10544 => 9484, 10545 => 9485,
10546 => 9486, 10547 => 9487, 10548 => 9488, 10549 => 9489, 10550 => 9490,
10551 => 9491, 10552 => 9492, 10553 => 9493, 10554 => 9494, 10555 => 9495,
10556 => 9496, 10557 => 9497, 10558 => 9498, 10559 => 9499, 10560 => 9500,
10561 => 9501, 10562 => 9502, 10563 => 9503, 10564 => 9504, 10565 => 9505,
10566 => 9506, 10567 => 9507, 10568 => 9508, 10569 => 9509, 10570 => 9510,
10571 => 9511, 10572 => 9512, 10573 => 9513, 10574 => 9514, 10575 => 9515,
10576 => 9516, 10577 => 9517, 10578 => 9518, 10579 => 9519, 10580 => 9520,
10581 => 9521, 10582 => 9522, 10583 => 9523, 10584 => 9524, 10585 => 9525,
10586 => 9526, 10587 => 9527, 10588 => 9528, 10589 => 9529, 10590 => 9530,
10591 => 9531, 10592 => 9532, 10593 => 9533, 10594 => 9534, 10595 => 9535,
10596 => 9536, 10597 => 9537, 10598 => 9538, 10599 => 9539, 10600 => 9540,
10601 => 9541, 10602 => 9542, 10603 => 9543, 10604 => 9544, 10605 => 9545,
10606 => 9546, 10607 => 9547, 12321 => 21834, 12322 => 38463, 12323 => 22467,
12324 => 25384, 12325 => 21710, 12326 => 21769, 12327 => 21696, 12328 => 30353,
12329 => 30284, 12330 => 34108, 12331 => 30702, 12332 => 33406, 12333 => 30861,
12334 => 29233, 12335 => 38552, 12336 => 38797, 12337 => 27688, 12338 => 23433,
12339 => 20474, 12340 => 25353, 12341 => 26263, 12342 => 23736, 12343 => 33018,
12344 => 26696, 12345 => 32942, 12346 => 26114, 12347 => 30414, 12348 => 20985,
12349 => 25942, 12350 => 29100, 12351 => 32753, 12352 => 34948, 12353 => 20658,
12354 => 22885, 12355 => 25034, 12356 => 28595, 12357 => 33453, 12358 => 25420,
12359 => 25170, 12360 => 21485, 12361 => 21543, 12362 => 31494, 12363 => 20843,
12364 => 30116, 12365 => 24052, 12366 => 25300, 12367 => 36299, 12368 => 38774,
12369 => 25226, 12370 => 32793, 12371 => 22365, 12372 => 38712, 12373 => 32610,
12374 => 29240, 12375 => 30333, 12376 => 26575, 12377 => 30334, 12378 => 25670,
12379 => 20336, 12380 => 36133, 12381 => 25308, 12382 => 31255, 12383 => 26001,
12384 => 29677, 12385 => 25644, 12386 => 25203, 12387 => 33324, 12388 => 39041,
12389 => 26495, 12390 => 29256, 12391 => 25198, 12392 => 25292, 12393 => 20276,
12394 => 29923, 12395 => 21322, 12396 => 21150, 12397 => 32458, 12398 => 37030,
12399 => 24110, 12400 => 26758, 12401 => 27036, 12402 => 33152, 12403 => 32465,
12404 => 26834, 12405 => 30917, 12406 => 34444, 12407 => 38225, 12408 => 20621,
12409 => 35876, 12410 => 33502, 12411 => 32990, 12412 => 21253, 12413 => 35090,
12414 => 21093, 12577 => 34180, 12578 => 38649, 12579 => 20445, 12580 => 22561,
12581 => 39281, 12582 => 23453, 12583 => 25265, 12584 => 25253, 12585 => 26292,
12586 => 35961, 12587 => 40077, 12588 => 29190, 12589 => 26479, 12590 => 30865,
12591 => 24754, 12592 => 21329, 12593 => 21271, 12594 => 36744, 12595 => 32972,
12596 => 36125, 12597 => 38049, 12598 => 20493, 12599 => 29384, 12600 => 22791,
12601 => 24811, 12602 => 28953, 12603 => 34987, 12604 => 22868, 12605 => 33519,
12606 => 26412, 12607 => 31528, 12608 => 23849, 12609 => 32503, 12610 => 29997,
12611 => 27893, 12612 => 36454, 12613 => 36856, 12614 => 36924, 12615 => 40763,
12616 => 27604, 12617 => 37145, 12618 => 31508, 12619 => 24444, 12620 => 30887,
12621 => 34006, 12622 => 34109, 12623 => 27605, 12624 => 27609, 12625 => 27606,
12626 => 24065, 12627 => 24199, 12628 => 30201, 12629 => 38381, 12630 => 25949,
12631 => 24330, 12632 => 24517, 12633 => 36767, 12634 => 22721, 12635 => 33218,
12636 => 36991, 12637 => 38491, 12638 => 38829, 12639 => 36793, 12640 => 32534,
12641 => 36140, 12642 => 25153, 12643 => 20415, 12644 => 21464, 12645 => 21342,
12646 => 36776, 12647 => 36777, 12648 => 36779, 12649 => 36941, 12650 => 26631,
12651 => 24426, 12652 => 33176, 12653 => 34920, 12654 => 40150, 12655 => 24971,
12656 => 21035, 12657 => 30250, 12658 => 24428, 12659 => 25996, 12660 => 28626,
12661 => 28392, 12662 => 23486, 12663 => 25672, 12664 => 20853, 12665 => 20912,
12666 => 26564, 12667 => 19993, 12668 => 31177, 12669 => 39292, 12670 => 28851,
12833 => 30149, 12834 => 24182, 12835 => 29627, 12836 => 33760, 12837 => 25773,
12838 => 25320, 12839 => 38069, 12840 => 27874, 12841 => 21338, 12842 => 21187,
12843 => 25615, 12844 => 38082, 12845 => 31636, 12846 => 20271, 12847 => 24091,
12848 => 33334, 12849 => 33046, 12850 => 33162, 12851 => 28196, 12852 => 27850,
12853 => 39539, 12854 => 25429, 12855 => 21340, 12856 => 21754, 12857 => 34917,
12858 => 22496, 12859 => 19981, 12860 => 24067, 12861 => 27493, 12862 => 31807,
12863 => 37096, 12864 => 24598, 12865 => 25830, 12866 => 29468, 12867 => 35009,
12868 => 26448, 12869 => 25165, 12870 => 36130, 12871 => 30572, 12872 => 36393,
12873 => 37319, 12874 => 24425, 12875 => 33756, 12876 => 34081, 12877 => 39184,
12878 => 21442, 12879 => 34453, 12880 => 27531, 12881 => 24813, 12882 => 24808,
12883 => 28799, 12884 => 33485, 12885 => 33329, 12886 => 20179, 12887 => 27815,
12888 => 34255, 12889 => 25805, 12890 => 31961, 12891 => 27133, 12892 => 26361,
12893 => 33609, 12894 => 21397, 12895 => 31574, 12896 => 20391, 12897 => 20876,
12898 => 27979, 12899 => 23618, 12900 => 36461, 12901 => 25554, 12902 => 21449,
12903 => 33580, 12904 => 33590, 12905 => 26597, 12906 => 30900, 12907 => 25661,
12908 => 23519, 12909 => 23700, 12910 => 24046, 12911 => 35815, 12912 => 25286,
12913 => 26612, 12914 => 35962, 12915 => 25600, 12916 => 25530, 12917 => 34633,
12918 => 39307, 12919 => 35863, 12920 => 32544, 12921 => 38130, 12922 => 20135,
12923 => 38416, 12924 => 39076, 12925 => 26124, 12926 => 29462, 13089 => 22330,
13090 => 23581, 13091 => 24120, 13092 => 38271, 13093 => 20607, 13094 => 32928,
13095 => 21378, 13096 => 25950, 13097 => 30021, 13098 => 21809, 13099 => 20513,
13100 => 36229, 13101 => 25220, 13102 => 38046, 13103 => 26397, 13104 => 22066,
13105 => 28526, 13106 => 24034, 13107 => 21557, 13108 => 28818, 13109 => 36710,
13110 => 25199, 13111 => 25764, 13112 => 25507, 13113 => 24443, 13114 => 28552,
13115 => 37108, 13116 => 33251, 13117 => 36784, 13118 => 23576, 13119 => 26216,
13120 => 24561, 13121 => 27785, 13122 => 38472, 13123 => 36225, 13124 => 34924,
13125 => 25745, 13126 => 31216, 13127 => 22478, 13128 => 27225, 13129 => 25104,
13130 => 21576, 13131 => 20056, 13132 => 31243, 13133 => 24809, 13134 => 28548,
13135 => 35802, 13136 => 25215, 13137 => 36894, 13138 => 39563, 13139 => 31204,
13140 => 21507, 13141 => 30196, 13142 => 25345, 13143 => 21273, 13144 => 27744,
13145 => 36831, 13146 => 24347, 13147 => 39536, 13148 => 32827, 13149 => 40831,
13150 => 20360, 13151 => 23610, 13152 => 36196, 13153 => 32709, 13154 => 26021,
13155 => 28861, 13156 => 20805, 13157 => 20914, 13158 => 34411, 13159 => 23815,
13160 => 23456, 13161 => 25277, 13162 => 37228, 13163 => 30068, 13164 => 36364,
13165 => 31264, 13166 => 24833, 13167 => 31609, 13168 => 20167, 13169 => 32504,
13170 => 30597, 13171 => 19985, 13172 => 33261, 13173 => 21021, 13174 => 20986,
13175 => 27249, 13176 => 21416, 13177 => 36487, 13178 => 38148, 13179 => 38607,
13180 => 28353, 13181 => 38500, 13182 => 26970, 13345 => 30784, 13346 => 20648,
13347 => 30679, 13348 => 25616, 13349 => 35302, 13350 => 22788, 13351 => 25571,
13352 => 24029, 13353 => 31359, 13354 => 26941, 13355 => 20256, 13356 => 33337,
13357 => 21912, 13358 => 20018, 13359 => 30126, 13360 => 31383, 13361 => 24162,
13362 => 24202, 13363 => 38383, 13364 => 21019, 13365 => 21561, 13366 => 28810,
13367 => 25462, 13368 => 38180, 13369 => 22402, 13370 => 26149, 13371 => 26943,
13372 => 37255, 13373 => 21767, 13374 => 28147, 13375 => 32431, 13376 => 34850,
13377 => 25139, 13378 => 32496, 13379 => 30133, 13380 => 33576, 13381 => 30913,
13382 => 38604, 13383 => 36766, 13384 => 24904, 13385 => 29943, 13386 => 35789,
13387 => 27492, 13388 => 21050, 13389 => 36176, 13390 => 27425, 13391 => 32874,
13392 => 33905, 13393 => 22257, 13394 => 21254, 13395 => 20174, 13396 => 19995,
13397 => 20945, 13398 => 31895, 13399 => 37259, 13400 => 31751, 13401 => 20419,
13402 => 36479, 13403 => 31713, 13404 => 31388, 13405 => 25703, 13406 => 23828,
13407 => 20652, 13408 => 33030, 13409 => 30209, 13410 => 31929, 13411 => 28140,
13412 => 32736, 13413 => 26449, 13414 => 23384, 13415 => 23544, 13416 => 30923,
13417 => 25774, 13418 => 25619, 13419 => 25514, 13420 => 25387, 13421 => 38169,
13422 => 25645, 13423 => 36798, 13424 => 31572, 13425 => 30249, 13426 => 25171,
13427 => 22823, 13428 => 21574, 13429 => 27513, 13430 => 20643, 13431 => 25140,
13432 => 24102, 13433 => 27526, 13434 => 20195, 13435 => 36151, 13436 => 34955,
13437 => 24453, 13438 => 36910, 13601 => 24608, 13602 => 32829, 13603 => 25285,
13604 => 20025, 13605 => 21333, 13606 => 37112, 13607 => 25528, 13608 => 32966,
13609 => 26086, 13610 => 27694, 13611 => 20294, 13612 => 24814, 13613 => 28129,
13614 => 35806, 13615 => 24377, 13616 => 34507, 13617 => 24403, 13618 => 25377,
13619 => 20826, 13620 => 33633, 13621 => 26723, 13622 => 20992, 13623 => 25443,
13624 => 36424, 13625 => 20498, 13626 => 23707, 13627 => 31095, 13628 => 23548,
13629 => 21040, 13630 => 31291, 13631 => 24764, 13632 => 36947, 13633 => 30423,
13634 => 24503, 13635 => 24471, 13636 => 30340, 13637 => 36460, 13638 => 28783,
13639 => 30331, 13640 => 31561, 13641 => 30634, 13642 => 20979, 13643 => 37011,
13644 => 22564, 13645 => 20302, 13646 => 28404, 13647 => 36842, 13648 => 25932,
13649 => 31515, 13650 => 29380, 13651 => 28068, 13652 => 32735, 13653 => 23265,
13654 => 25269, 13655 => 24213, 13656 => 22320, 13657 => 33922, 13658 => 31532,
13659 => 24093, 13660 => 24351, 13661 => 36882, 13662 => 32532, 13663 => 39072,
13664 => 25474, 13665 => 28359, 13666 => 30872, 13667 => 28857, 13668 => 20856,
13669 => 38747, 13670 => 22443, 13671 => 30005, 13672 => 20291, 13673 => 30008,
13674 => 24215, 13675 => 24806, 13676 => 22880, 13677 => 28096, 13678 => 27583,
13679 => 30857, 13680 => 21500, 13681 => 38613, 13682 => 20939, 13683 => 20993,
13684 => 25481, 13685 => 21514, 13686 => 38035, 13687 => 35843, 13688 => 36300,
13689 => 29241, 13690 => 30879, 13691 => 34678, 13692 => 36845, 13693 => 35853,
13694 => 21472, 13857 => 19969, 13858 => 30447, 13859 => 21486, 13860 => 38025,
13861 => 39030, 13862 => 40718, 13863 => 38189, 13864 => 23450, 13865 => 35746,
13866 => 20002, 13867 => 19996, 13868 => 20908, 13869 => 33891, 13870 => 25026,
13871 => 21160, 13872 => 26635, 13873 => 20375, 13874 => 24683, 13875 => 20923,
13876 => 27934, 13877 => 20828, 13878 => 25238, 13879 => 26007, 13880 => 38497,
13881 => 35910, 13882 => 36887, 13883 => 30168, 13884 => 37117, 13885 => 30563,
13886 => 27602, 13887 => 29322, 13888 => 29420, 13889 => 35835, 13890 => 22581,
13891 => 30585, 13892 => 36172, 13893 => 26460, 13894 => 38208, 13895 => 32922,
13896 => 24230, 13897 => 28193, 13898 => 22930, 13899 => 31471, 13900 => 30701,
13901 => 38203, 13902 => 27573, 13903 => 26029, 13904 => 32526, 13905 => 22534,
13906 => 20817, 13907 => 38431, 13908 => 23545, 13909 => 22697, 13910 => 21544,
13911 => 36466, 13912 => 25958, 13913 => 39039, 13914 => 22244, 13915 => 38045,
13916 => 30462, 13917 => 36929, 13918 => 25479, 13919 => 21702, 13920 => 22810,
13921 => 22842, 13922 => 22427, 13923 => 36530, 13924 => 26421, 13925 => 36346,
13926 => 33333, 13927 => 21057, 13928 => 24816, 13929 => 22549, 13930 => 34558,
13931 => 23784, 13932 => 40517, 13933 => 20420, 13934 => 39069, 13935 => 35769,
13936 => 23077, 13937 => 24694, 13938 => 21380, 13939 => 25212, 13940 => 36943,
13941 => 37122, 13942 => 39295, 13943 => 24681, 13944 => 32780, 13945 => 20799,
13946 => 32819, 13947 => 23572, 13948 => 39285, 13949 => 27953, 13950 => 20108,
14113 => 36144, 14114 => 21457, 14115 => 32602, 14116 => 31567, 14117 => 20240,
14118 => 20047, 14119 => 38400, 14120 => 27861, 14121 => 29648, 14122 => 34281,
14123 => 24070, 14124 => 30058, 14125 => 32763, 14126 => 27146, 14127 => 30718,
14128 => 38034, 14129 => 32321, 14130 => 20961, 14131 => 28902, 14132 => 21453,
14133 => 36820, 14134 => 33539, 14135 => 36137, 14136 => 29359, 14137 => 39277,
14138 => 27867, 14139 => 22346, 14140 => 33459, 14141 => 26041, 14142 => 32938,
14143 => 25151, 14144 => 38450, 14145 => 22952, 14146 => 20223, 14147 => 35775,
14148 => 32442, 14149 => 25918, 14150 => 33778, 14151 => 38750, 14152 => 21857,
14153 => 39134, 14154 => 32933, 14155 => 21290, 14156 => 35837, 14157 => 21536,
14158 => 32954, 14159 => 24223, 14160 => 27832, 14161 => 36153, 14162 => 33452,
14163 => 37210, 14164 => 21545, 14165 => 27675, 14166 => 20998, 14167 => 32439,
14168 => 22367, 14169 => 28954, 14170 => 27774, 14171 => 31881, 14172 => 22859,
14173 => 20221, 14174 => 24575, 14175 => 24868, 14176 => 31914, 14177 => 20016,
14178 => 23553, 14179 => 26539, 14180 => 34562, 14181 => 23792, 14182 => 38155,
14183 => 39118, 14184 => 30127, 14185 => 28925, 14186 => 36898, 14187 => 20911,
14188 => 32541, 14189 => 35773, 14190 => 22857, 14191 => 20964, 14192 => 20315,
14193 => 21542, 14194 => 22827, 14195 => 25975, 14196 => 32932, 14197 => 23413,
14198 => 25206, 14199 => 25282, 14200 => 36752, 14201 => 24133, 14202 => 27679,
14203 => 31526, 14204 => 20239, 14205 => 20440, 14206 => 26381, 14369 => 28014,
14370 => 28074, 14371 => 31119, 14372 => 34993, 14373 => 24343, 14374 => 29995,
14375 => 25242, 14376 => 36741, 14377 => 20463, 14378 => 37340, 14379 => 26023,
14380 => 33071, 14381 => 33105, 14382 => 24220, 14383 => 33104, 14384 => 36212,
14385 => 21103, 14386 => 35206, 14387 => 36171, 14388 => 22797, 14389 => 20613,
14390 => 20184, 14391 => 38428, 14392 => 29238, 14393 => 33145, 14394 => 36127,
14395 => 23500, 14396 => 35747, 14397 => 38468, 14398 => 22919, 14399 => 32538,
14400 => 21648, 14401 => 22134, 14402 => 22030, 14403 => 35813, 14404 => 25913,
14405 => 27010, 14406 => 38041, 14407 => 30422, 14408 => 28297, 14409 => 24178,
14410 => 29976, 14411 => 26438, 14412 => 26577, 14413 => 31487, 14414 => 32925,
14415 => 36214, 14416 => 24863, 14417 => 31174, 14418 => 25954, 14419 => 36195,
14420 => 20872, 14421 => 21018, 14422 => 38050, 14423 => 32568, 14424 => 32923,
14425 => 32434, 14426 => 23703, 14427 => 28207, 14428 => 26464, 14429 => 31705,
14430 => 30347, 14431 => 39640, 14432 => 33167, 14433 => 32660, 14434 => 31957,
14435 => 25630, 14436 => 38224, 14437 => 31295, 14438 => 21578, 14439 => 21733,
14440 => 27468, 14441 => 25601, 14442 => 25096, 14443 => 40509, 14444 => 33011,
14445 => 30105, 14446 => 21106, 14447 => 38761, 14448 => 33883, 14449 => 26684,
14450 => 34532, 14451 => 38401, 14452 => 38548, 14453 => 38124, 14454 => 20010,
14455 => 21508, 14456 => 32473, 14457 => 26681, 14458 => 36319, 14459 => 32789,
14460 => 26356, 14461 => 24218, 14462 => 32697, 14625 => 22466, 14626 => 32831,
14627 => 26775, 14628 => 24037, 14629 => 25915, 14630 => 21151, 14631 => 24685,
14632 => 40858, 14633 => 20379, 14634 => 36524, 14635 => 20844, 14636 => 23467,
14637 => 24339, 14638 => 24041, 14639 => 27742, 14640 => 25329, 14641 => 36129,
14642 => 20849, 14643 => 38057, 14644 => 21246, 14645 => 27807, 14646 => 33503,
14647 => 29399, 14648 => 22434, 14649 => 26500, 14650 => 36141, 14651 => 22815,
14652 => 36764, 14653 => 33735, 14654 => 21653, 14655 => 31629, 14656 => 20272,
14657 => 27837, 14658 => 23396, 14659 => 22993, 14660 => 40723, 14661 => 21476,
14662 => 34506, 14663 => 39592, 14664 => 35895, 14665 => 32929, 14666 => 25925,
14667 => 39038, 14668 => 22266, 14669 => 38599, 14670 => 21038, 14671 => 29916,
14672 => 21072, 14673 => 23521, 14674 => 25346, 14675 => 35074, 14676 => 20054,
14677 => 25296, 14678 => 24618, 14679 => 26874, 14680 => 20851, 14681 => 23448,
14682 => 20896, 14683 => 35266, 14684 => 31649, 14685 => 39302, 14686 => 32592,
14687 => 24815, 14688 => 28748, 14689 => 36143, 14690 => 20809, 14691 => 24191,
14692 => 36891, 14693 => 29808, 14694 => 35268, 14695 => 22317, 14696 => 30789,
14697 => 24402, 14698 => 40863, 14699 => 38394, 14700 => 36712, 14701 => 39740,
14702 => 35809, 14703 => 30328, 14704 => 26690, 14705 => 26588, 14706 => 36330,
14707 => 36149, 14708 => 21053, 14709 => 36746, 14710 => 28378, 14711 => 26829,
14712 => 38149, 14713 => 37101, 14714 => 22269, 14715 => 26524, 14716 => 35065,
14717 => 36807, 14718 => 21704, 14881 => 39608, 14882 => 23401, 14883 => 28023,
14884 => 27686, 14885 => 20133, 14886 => 23475, 14887 => 39559, 14888 => 37219,
14889 => 25000, 14890 => 37039, 14891 => 38889, 14892 => 21547, 14893 => 28085,
14894 => 23506, 14895 => 20989, 14896 => 21898, 14897 => 32597, 14898 => 32752,
14899 => 25788, 14900 => 25421, 14901 => 26097, 14902 => 25022, 14903 => 24717,
14904 => 28938, 14905 => 27735, 14906 => 27721, 14907 => 22831, 14908 => 26477,
14909 => 33322, 14910 => 22741, 14911 => 22158, 14912 => 35946, 14913 => 27627,
14914 => 37085, 14915 => 22909, 14916 => 32791, 14917 => 21495, 14918 => 28009,
14919 => 21621, 14920 => 21917, 14921 => 33655, 14922 => 33743, 14923 => 26680,
14924 => 31166, 14925 => 21644, 14926 => 20309, 14927 => 21512, 14928 => 30418,
14929 => 35977, 14930 => 38402, 14931 => 27827, 14932 => 28088, 14933 => 36203,
14934 => 35088, 14935 => 40548, 14936 => 36154, 14937 => 22079, 14938 => 40657,
14939 => 30165, 14940 => 24456, 14941 => 29408, 14942 => 24680, 14943 => 21756,
14944 => 20136, 14945 => 27178, 14946 => 34913, 14947 => 24658, 14948 => 36720,
14949 => 21700, 14950 => 28888, 14951 => 34425, 14952 => 40511, 14953 => 27946,
14954 => 23439, 14955 => 24344, 14956 => 32418, 14957 => 21897, 14958 => 20399,
14959 => 29492, 14960 => 21564, 14961 => 21402, 14962 => 20505, 14963 => 21518,
14964 => 21628, 14965 => 20046, 14966 => 24573, 14967 => 29786, 14968 => 22774,
14969 => 33899, 14970 => 32993, 14971 => 34676, 14972 => 29392, 14973 => 31946,
14974 => 28246, 15137 => 24359, 15138 => 34382, 15139 => 21804, 15140 => 25252,
15141 => 20114, 15142 => 27818, 15143 => 25143, 15144 => 33457, 15145 => 21719,
15146 => 21326, 15147 => 29502, 15148 => 28369, 15149 => 30011, 15150 => 21010,
15151 => 21270, 15152 => 35805, 15153 => 27088, 15154 => 24458, 15155 => 24576,
15156 => 28142, 15157 => 22351, 15158 => 27426, 15159 => 29615, 15160 => 26707,
15161 => 36824, 15162 => 32531, 15163 => 25442, 15164 => 24739, 15165 => 21796,
15166 => 30186, 15167 => 35938, 15168 => 28949, 15169 => 28067, 15170 => 23462,
15171 => 24187, 15172 => 33618, 15173 => 24908, 15174 => 40644, 15175 => 30970,
15176 => 34647, 15177 => 31783, 15178 => 30343, 15179 => 20976, 15180 => 24822,
15181 => 29004, 15182 => 26179, 15183 => 24140, 15184 => 24653, 15185 => 35854,
15186 => 28784, 15187 => 25381, 15188 => 36745, 15189 => 24509, 15190 => 24674,
15191 => 34516, 15192 => 22238, 15193 => 27585, 15194 => 24724, 15195 => 24935,
15196 => 21321, 15197 => 24800, 15198 => 26214, 15199 => 36159, 15200 => 31229,
15201 => 20250, 15202 => 28905, 15203 => 27719, 15204 => 35763, 15205 => 35826,
15206 => 32472, 15207 => 33636, 15208 => 26127, 15209 => 23130, 15210 => 39746,
15211 => 27985, 15212 => 28151, 15213 => 35905, 15214 => 27963, 15215 => 20249,
15216 => 28779, 15217 => 33719, 15218 => 25110, 15219 => 24785, 15220 => 38669,
15221 => 36135, 15222 => 31096, 15223 => 20987, 15224 => 22334, 15225 => 22522,
15226 => 26426, 15227 => 30072, 15228 => 31293, 15229 => 31215, 15230 => 31637,
15393 => 32908, 15394 => 39269, 15395 => 36857, 15396 => 28608, 15397 => 35749,
15398 => 40481, 15399 => 23020, 15400 => 32489, 15401 => 32521, 15402 => 21513,
15403 => 26497, 15404 => 26840, 15405 => 36753, 15406 => 31821, 15407 => 38598,
15408 => 21450, 15409 => 24613, 15410 => 30142, 15411 => 27762, 15412 => 21363,
15413 => 23241, 15414 => 32423, 15415 => 25380, 15416 => 20960, 15417 => 33034,
15418 => 24049, 15419 => 34015, 15420 => 25216, 15421 => 20864, 15422 => 23395,
15423 => 20238, 15424 => 31085, 15425 => 21058, 15426 => 24760, 15427 => 27982,
15428 => 23492, 15429 => 23490, 15430 => 35745, 15431 => 35760, 15432 => 26082,
15433 => 24524, 15434 => 38469, 15435 => 22931, 15436 => 32487, 15437 => 32426,
15438 => 22025, 15439 => 26551, 15440 => 22841, 15441 => 20339, 15442 => 23478,
15443 => 21152, 15444 => 33626, 15445 => 39050, 15446 => 36158, 15447 => 30002,
15448 => 38078, 15449 => 20551, 15450 => 31292, 15451 => 20215, 15452 => 26550,
15453 => 39550, 15454 => 23233, 15455 => 27516, 15456 => 30417, 15457 => 22362,
15458 => 23574, 15459 => 31546, 15460 => 38388, 15461 => 29006, 15462 => 20860,
15463 => 32937, 15464 => 33392, 15465 => 22904, 15466 => 32516, 15467 => 33575,
15468 => 26816, 15469 => 26604, 15470 => 30897, 15471 => 30839, 15472 => 25315,
15473 => 25441, 15474 => 31616, 15475 => 20461, 15476 => 21098, 15477 => 20943,
15478 => 33616, 15479 => 27099, 15480 => 37492, 15481 => 36341, 15482 => 36145,
15483 => 35265, 15484 => 38190, 15485 => 31661, 15486 => 20214, 15649 => 20581,
15650 => 33328, 15651 => 21073, 15652 => 39279, 15653 => 28176, 15654 => 28293,
15655 => 28071, 15656 => 24314, 15657 => 20725, 15658 => 23004, 15659 => 23558,
15660 => 27974, 15661 => 27743, 15662 => 30086, 15663 => 33931, 15664 => 26728,
15665 => 22870, 15666 => 35762, 15667 => 21280, 15668 => 37233, 15669 => 38477,
15670 => 34121, 15671 => 26898, 15672 => 30977, 15673 => 28966, 15674 => 33014,
15675 => 20132, 15676 => 37066, 15677 => 27975, 15678 => 39556, 15679 => 23047,
15680 => 22204, 15681 => 25605, 15682 => 38128, 15683 => 30699, 15684 => 20389,
15685 => 33050, 15686 => 29409, 15687 => 35282, 15688 => 39290, 15689 => 32564,
15690 => 32478, 15691 => 21119, 15692 => 25945, 15693 => 37237, 15694 => 36735,
15695 => 36739, 15696 => 21483, 15697 => 31382, 15698 => 25581, 15699 => 25509,
15700 => 30342, 15701 => 31224, 15702 => 34903, 15703 => 38454, 15704 => 25130,
15705 => 21163, 15706 => 33410, 15707 => 26708, 15708 => 26480, 15709 => 25463,
15710 => 30571, 15711 => 31469, 15712 => 27905, 15713 => 32467, 15714 => 35299,
15715 => 22992, 15716 => 25106, 15717 => 34249, 15718 => 33445, 15719 => 30028,
15720 => 20511, 15721 => 20171, 15722 => 30117, 15723 => 35819, 15724 => 23626,
15725 => 24062, 15726 => 31563, 15727 => 26020, 15728 => 37329, 15729 => 20170,
15730 => 27941, 15731 => 35167, 15732 => 32039, 15733 => 38182, 15734 => 20165,
15735 => 35880, 15736 => 36827, 15737 => 38771, 15738 => 26187, 15739 => 31105,
15740 => 36817, 15741 => 28908, 15742 => 28024, 15905 => 23613, 15906 => 21170,
15907 => 33606, 15908 => 20834, 15909 => 33550, 15910 => 30555, 15911 => 26230,
15912 => 40120, 15913 => 20140, 15914 => 24778, 15915 => 31934, 15916 => 31923,
15917 => 32463, 15918 => 20117, 15919 => 35686, 15920 => 26223, 15921 => 39048,
15922 => 38745, 15923 => 22659, 15924 => 25964, 15925 => 38236, 15926 => 24452,
15927 => 30153, 15928 => 38742, 15929 => 31455, 15930 => 31454, 15931 => 20928,
15932 => 28847, 15933 => 31384, 15934 => 25578, 15935 => 31350, 15936 => 32416,
15937 => 29590, 15938 => 38893, 15939 => 20037, 15940 => 28792, 15941 => 20061,
15942 => 37202, 15943 => 21417, 15944 => 25937, 15945 => 26087, 15946 => 33276,
15947 => 33285, 15948 => 21646, 15949 => 23601, 15950 => 30106, 15951 => 38816,
15952 => 25304, 15953 => 29401, 15954 => 30141, 15955 => 23621, 15956 => 39545,
15957 => 33738, 15958 => 23616, 15959 => 21632, 15960 => 30697, 15961 => 20030,
15962 => 27822, 15963 => 32858, 15964 => 25298, 15965 => 25454, 15966 => 24040,
15967 => 20855, 15968 => 36317, 15969 => 36382, 15970 => 38191, 15971 => 20465,
15972 => 21477, 15973 => 24807, 15974 => 28844, 15975 => 21095, 15976 => 25424,
15977 => 40515, 15978 => 23071, 15979 => 20518, 15980 => 30519, 15981 => 21367,
15982 => 32482, 15983 => 25733, 15984 => 25899, 15985 => 25225, 15986 => 25496,
15987 => 20500, 15988 => 29237, 15989 => 35273, 15990 => 20915, 15991 => 35776,
15992 => 32477, 15993 => 22343, 15994 => 33740, 15995 => 38055, 15996 => 20891,
15997 => 21531, 15998 => 23803, 16161 => 20426, 16162 => 31459, 16163 => 27994,
16164 => 37089, 16165 => 39567, 16166 => 21888, 16167 => 21654, 16168 => 21345,
16169 => 21679, 16170 => 24320, 16171 => 25577, 16172 => 26999, 16173 => 20975,
16174 => 24936, 16175 => 21002, 16176 => 22570, 16177 => 21208, 16178 => 22350,
16179 => 30733, 16180 => 30475, 16181 => 24247, 16182 => 24951, 16183 => 31968,
16184 => 25179, 16185 => 25239, 16186 => 20130, 16187 => 28821, 16188 => 32771,
16189 => 25335, 16190 => 28900, 16191 => 38752, 16192 => 22391, 16193 => 33499,
16194 => 26607, 16195 => 26869, 16196 => 30933, 16197 => 39063, 16198 => 31185,
16199 => 22771, 16200 => 21683, 16201 => 21487, 16202 => 28212, 16203 => 20811,
16204 => 21051, 16205 => 23458, 16206 => 35838, 16207 => 32943, 16208 => 21827,
16209 => 22438, 16210 => 24691, 16211 => 22353, 16212 => 21549, 16213 => 31354,
16214 => 24656, 16215 => 23380, 16216 => 25511, 16217 => 25248, 16218 => 21475,
16219 => 25187, 16220 => 23495, 16221 => 26543, 16222 => 21741, 16223 => 31391,
16224 => 33510, 16225 => 37239, 16226 => 24211, 16227 => 35044, 16228 => 22840,
16229 => 22446, 16230 => 25358, 16231 => 36328, 16232 => 33007, 16233 => 22359,
16234 => 31607, 16235 => 20393, 16236 => 24555, 16237 => 23485, 16238 => 27454,
16239 => 21281, 16240 => 31568, 16241 => 29378, 16242 => 26694, 16243 => 30719,
16244 => 30518, 16245 => 26103, 16246 => 20917, 16247 => 20111, 16248 => 30420,
16249 => 23743, 16250 => 31397, 16251 => 33909, 16252 => 22862, 16253 => 39745,
16254 => 20608, 16417 => 39304, 16418 => 24871, 16419 => 28291, 16420 => 22372,
16421 => 26118, 16422 => 25414, 16423 => 22256, 16424 => 25324, 16425 => 25193,
16426 => 24275, 16427 => 38420, 16428 => 22403, 16429 => 25289, 16430 => 21895,
16431 => 34593, 16432 => 33098, 16433 => 36771, 16434 => 21862, 16435 => 33713,
16436 => 26469, 16437 => 36182, 16438 => 34013, 16439 => 23146, 16440 => 26639,
16441 => 25318, 16442 => 31726, 16443 => 38417, 16444 => 20848, 16445 => 28572,
16446 => 35888, 16447 => 25597, 16448 => 35272, 16449 => 25042, 16450 => 32518,
16451 => 28866, 16452 => 28389, 16453 => 29701, 16454 => 27028, 16455 => 29436,
16456 => 24266, 16457 => 37070, 16458 => 26391, 16459 => 28010, 16460 => 25438,
16461 => 21171, 16462 => 29282, 16463 => 32769, 16464 => 20332, 16465 => 23013,
16466 => 37226, 16467 => 28889, 16468 => 28061, 16469 => 21202, 16470 => 20048,
16471 => 38647, 16472 => 38253, 16473 => 34174, 16474 => 30922, 16475 => 32047,
16476 => 20769, 16477 => 22418, 16478 => 25794, 16479 => 32907, 16480 => 31867,
16481 => 27882, 16482 => 26865, 16483 => 26974, 16484 => 20919, 16485 => 21400,
16486 => 26792, 16487 => 29313, 16488 => 40654, 16489 => 31729, 16490 => 29432,
16491 => 31163, 16492 => 28435, 16493 => 29702, 16494 => 26446, 16495 => 37324,
16496 => 40100, 16497 => 31036, 16498 => 33673, 16499 => 33620, 16500 => 21519,
16501 => 26647, 16502 => 20029, 16503 => 21385, 16504 => 21169, 16505 => 30782,
16506 => 21382, 16507 => 21033, 16508 => 20616, 16509 => 20363, 16510 => 20432,
16673 => 30178, 16674 => 31435, 16675 => 31890, 16676 => 27813, 16677 => 38582,
16678 => 21147, 16679 => 29827, 16680 => 21737, 16681 => 20457, 16682 => 32852,
16683 => 33714, 16684 => 36830, 16685 => 38256, 16686 => 24265, 16687 => 24604,
16688 => 28063, 16689 => 24088, 16690 => 25947, 16691 => 33080, 16692 => 38142,
16693 => 24651, 16694 => 28860, 16695 => 32451, 16696 => 31918, 16697 => 20937,
16698 => 26753, 16699 => 31921, 16700 => 33391, 16701 => 20004, 16702 => 36742,
16703 => 37327, 16704 => 26238, 16705 => 20142, 16706 => 35845, 16707 => 25769,
16708 => 32842, 16709 => 20698, 16710 => 30103, 16711 => 29134, 16712 => 23525,
16713 => 36797, 16714 => 28518, 16715 => 20102, 16716 => 25730, 16717 => 38243,
16718 => 24278, 16719 => 26009, 16720 => 21015, 16721 => 35010, 16722 => 28872,
16723 => 21155, 16724 => 29454, 16725 => 29747, 16726 => 26519, 16727 => 30967,
16728 => 38678, 16729 => 20020, 16730 => 37051, 16731 => 40158, 16732 => 28107,
16733 => 20955, 16734 => 36161, 16735 => 21533, 16736 => 25294, 16737 => 29618,
16738 => 33777, 16739 => 38646, 16740 => 40836, 16741 => 38083, 16742 => 20278,
16743 => 32666, 16744 => 20940, 16745 => 28789, 16746 => 38517, 16747 => 23725,
16748 => 39046, 16749 => 21478, 16750 => 20196, 16751 => 28316, 16752 => 29705,
16753 => 27060, 16754 => 30827, 16755 => 39311, 16756 => 30041, 16757 => 21016,
16758 => 30244, 16759 => 27969, 16760 => 26611, 16761 => 20845, 16762 => 40857,
16763 => 32843, 16764 => 21657, 16765 => 31548, 16766 => 31423, 16929 => 38534,
16930 => 22404, 16931 => 25314, 16932 => 38471, 16933 => 27004, 16934 => 23044,
16935 => 25602, 16936 => 31699, 16937 => 28431, 16938 => 38475, 16939 => 33446,
16940 => 21346, 16941 => 39045, 16942 => 24208, 16943 => 28809, 16944 => 25523,
16945 => 21348, 16946 => 34383, 16947 => 40065, 16948 => 40595, 16949 => 30860,
16950 => 38706, 16951 => 36335, 16952 => 36162, 16953 => 40575, 16954 => 28510,
16955 => 31108, 16956 => 24405, 16957 => 38470, 16958 => 25134, 16959 => 39540,
16960 => 21525, 16961 => 38109, 16962 => 20387, 16963 => 26053, 16964 => 23653,
16965 => 23649, 16966 => 32533, 16967 => 34385, 16968 => 27695, 16969 => 24459,
16970 => 29575, 16971 => 28388, 16972 => 32511, 16973 => 23782, 16974 => 25371,
16975 => 23402, 16976 => 28390, 16977 => 21365, 16978 => 20081, 16979 => 25504,
16980 => 30053, 16981 => 25249, 16982 => 36718, 16983 => 20262, 16984 => 20177,
16985 => 27814, 16986 => 32438, 16987 => 35770, 16988 => 33821, 16989 => 34746,
16990 => 32599, 16991 => 36923, 16992 => 38179, 16993 => 31657, 16994 => 39585,
16995 => 35064, 16996 => 33853, 16997 => 27931, 16998 => 39558, 16999 => 32476,
17000 => 22920, 17001 => 40635, 17002 => 29595, 17003 => 30721, 17004 => 34434,
17005 => 39532, 17006 => 39554, 17007 => 22043, 17008 => 21527, 17009 => 22475,
17010 => 20080, 17011 => 40614, 17012 => 21334, 17013 => 36808, 17014 => 33033,
17015 => 30610, 17016 => 39314, 17017 => 34542, 17018 => 28385, 17019 => 34067,
17020 => 26364, 17021 => 24930, 17022 => 28459, 17185 => 35881, 17186 => 33426,
17187 => 33579, 17188 => 30450, 17189 => 27667, 17190 => 24537, 17191 => 33725,
17192 => 29483, 17193 => 33541, 17194 => 38170, 17195 => 27611, 17196 => 30683,
17197 => 38086, 17198 => 21359, 17199 => 33538, 17200 => 20882, 17201 => 24125,
17202 => 35980, 17203 => 36152, 17204 => 20040, 17205 => 29611, 17206 => 26522,
17207 => 26757, 17208 => 37238, 17209 => 38665, 17210 => 29028, 17211 => 27809,
17212 => 30473, 17213 => 23186, 17214 => 38209, 17215 => 27599, 17216 => 32654,
17217 => 26151, 17218 => 23504, 17219 => 22969, 17220 => 23194, 17221 => 38376,
17222 => 38391, 17223 => 20204, 17224 => 33804, 17225 => 33945, 17226 => 27308,
17227 => 30431, 17228 => 38192, 17229 => 29467, 17230 => 26790, 17231 => 23391,
17232 => 30511, 17233 => 37274, 17234 => 38753, 17235 => 31964, 17236 => 36855,
17237 => 35868, 17238 => 24357, 17239 => 31859, 17240 => 31192, 17241 => 35269,
17242 => 27852, 17243 => 34588, 17244 => 23494, 17245 => 24130, 17246 => 26825,
17247 => 30496, 17248 => 32501, 17249 => 20885, 17250 => 20813, 17251 => 21193,
17252 => 23081, 17253 => 32517, 17254 => 38754, 17255 => 33495, 17256 => 25551,
17257 => 30596, 17258 => 34256, 17259 => 31186, 17260 => 28218, 17261 => 24217,
17262 => 22937, 17263 => 34065, 17264 => 28781, 17265 => 27665, 17266 => 25279,
17267 => 30399, 17268 => 25935, 17269 => 24751, 17270 => 38397, 17271 => 26126,
17272 => 34719, 17273 => 40483, 17274 => 38125, 17275 => 21517, 17276 => 21629,
17277 => 35884, 17278 => 25720, 17441 => 25721, 17442 => 34321, 17443 => 27169,
17444 => 33180, 17445 => 30952, 17446 => 25705, 17447 => 39764, 17448 => 25273,
17449 => 26411, 17450 => 33707, 17451 => 22696, 17452 => 40664, 17453 => 27819,
17454 => 28448, 17455 => 23518, 17456 => 38476, 17457 => 35851, 17458 => 29279,
17459 => 26576, 17460 => 25287, 17461 => 29281, 17462 => 20137, 17463 => 22982,
17464 => 27597, 17465 => 22675, 17466 => 26286, 17467 => 24149, 17468 => 21215,
17469 => 24917, 17470 => 26408, 17471 => 30446, 17472 => 30566, 17473 => 29287,
17474 => 31302, 17475 => 25343, 17476 => 21738, 17477 => 21584, 17478 => 38048,
17479 => 37027, 17480 => 23068, 17481 => 32435, 17482 => 27670, 17483 => 20035,
17484 => 22902, 17485 => 32784, 17486 => 22856, 17487 => 21335, 17488 => 30007,
17489 => 38590, 17490 => 22218, 17491 => 25376, 17492 => 33041, 17493 => 24700,
17494 => 38393, 17495 => 28118, 17496 => 21602, 17497 => 39297, 17498 => 20869,
17499 => 23273, 17500 => 33021, 17501 => 22958, 17502 => 38675, 17503 => 20522,
17504 => 27877, 17505 => 23612, 17506 => 25311, 17507 => 20320, 17508 => 21311,
17509 => 33147, 17510 => 36870, 17511 => 28346, 17512 => 34091, 17513 => 25288,
17514 => 24180, 17515 => 30910, 17516 => 25781, 17517 => 25467, 17518 => 24565,
17519 => 23064, 17520 => 37247, 17521 => 40479, 17522 => 23615, 17523 => 25423,
17524 => 32834, 17525 => 23421, 17526 => 21870, 17527 => 38218, 17528 => 38221,
17529 => 28037, 17530 => 24744, 17531 => 26592, 17532 => 29406, 17533 => 20957,
17534 => 23425, 17697 => 25319, 17698 => 27870, 17699 => 29275, 17700 => 25197,
17701 => 38062, 17702 => 32445, 17703 => 33043, 17704 => 27987, 17705 => 20892,
17706 => 24324, 17707 => 22900, 17708 => 21162, 17709 => 24594, 17710 => 22899,
17711 => 26262, 17712 => 34384, 17713 => 30111, 17714 => 25386, 17715 => 25062,
17716 => 31983, 17717 => 35834, 17718 => 21734, 17719 => 27431, 17720 => 40485,
17721 => 27572, 17722 => 34261, 17723 => 21589, 17724 => 20598, 17725 => 27812,
17726 => 21866, 17727 => 36276, 17728 => 29228, 17729 => 24085, 17730 => 24597,
17731 => 29750, 17732 => 25293, 17733 => 25490, 17734 => 29260, 17735 => 24472,
17736 => 28227, 17737 => 27966, 17738 => 25856, 17739 => 28504, 17740 => 30424,
17741 => 30928, 17742 => 30460, 17743 => 30036, 17744 => 21028, 17745 => 21467,
17746 => 20051, 17747 => 24222, 17748 => 26049, 17749 => 32810, 17750 => 32982,
17751 => 25243, 17752 => 21638, 17753 => 21032, 17754 => 28846, 17755 => 34957,
17756 => 36305, 17757 => 27873, 17758 => 21624, 17759 => 32986, 17760 => 22521,
17761 => 35060, 17762 => 36180, 17763 => 38506, 17764 => 37197, 17765 => 20329,
17766 => 27803, 17767 => 21943, 17768 => 30406, 17769 => 30768, 17770 => 25256,
17771 => 28921, 17772 => 28558, 17773 => 24429, 17774 => 34028, 17775 => 26842,
17776 => 30844, 17777 => 31735, 17778 => 33192, 17779 => 26379, 17780 => 40527,
17781 => 25447, 17782 => 30896, 17783 => 22383, 17784 => 30738, 17785 => 38713,
17786 => 25209, 17787 => 25259, 17788 => 21128, 17789 => 29749, 17790 => 27607,
17953 => 21860, 17954 => 33086, 17955 => 30130, 17956 => 30382, 17957 => 21305,
17958 => 30174, 17959 => 20731, 17960 => 23617, 17961 => 35692, 17962 => 31687,
17963 => 20559, 17964 => 29255, 17965 => 39575, 17966 => 39128, 17967 => 28418,
17968 => 29922, 17969 => 31080, 17970 => 25735, 17971 => 30629, 17972 => 25340,
17973 => 39057, 17974 => 36139, 17975 => 21697, 17976 => 32856, 17977 => 20050,
17978 => 22378, 17979 => 33529, 17980 => 33805, 17981 => 24179, 17982 => 20973,
17983 => 29942, 17984 => 35780, 17985 => 23631, 17986 => 22369, 17987 => 27900,
17988 => 39047, 17989 => 23110, 17990 => 30772, 17991 => 39748, 17992 => 36843,
17993 => 31893, 17994 => 21078, 17995 => 25169, 17996 => 38138, 17997 => 20166,
17998 => 33670, 17999 => 33889, 18000 => 33769, 18001 => 33970, 18002 => 22484,
18003 => 26420, 18004 => 22275, 18005 => 26222, 18006 => 28006, 18007 => 35889,
18008 => 26333, 18009 => 28689, 18010 => 26399, 18011 => 27450, 18012 => 26646,
18013 => 25114, 18014 => 22971, 18015 => 19971, 18016 => 20932, 18017 => 28422,
18018 => 26578, 18019 => 27791, 18020 => 20854, 18021 => 26827, 18022 => 22855,
18023 => 27495, 18024 => 30054, 18025 => 23822, 18026 => 33040, 18027 => 40784,
18028 => 26071, 18029 => 31048, 18030 => 31041, 18031 => 39569, 18032 => 36215,
18033 => 23682, 18034 => 20062, 18035 => 20225, 18036 => 21551, 18037 => 22865,
18038 => 30732, 18039 => 22120, 18040 => 27668, 18041 => 36804, 18042 => 24323,
18043 => 27773, 18044 => 27875, 18045 => 35755, 18046 => 25488, 18209 => 24688,
18210 => 27965, 18211 => 29301, 18212 => 25190, 18213 => 38030, 18214 => 38085,
18215 => 21315, 18216 => 36801, 18217 => 31614, 18218 => 20191, 18219 => 35878,
18220 => 20094, 18221 => 40660, 18222 => 38065, 18223 => 38067, 18224 => 21069,
18225 => 28508, 18226 => 36963, 18227 => 27973, 18228 => 35892, 18229 => 22545,
18230 => 23884, 18231 => 27424, 18232 => 27465, 18233 => 26538, 18234 => 21595,
18235 => 33108, 18236 => 32652, 18237 => 22681, 18238 => 34103, 18239 => 24378,
18240 => 25250, 18241 => 27207, 18242 => 38201, 18243 => 25970, 18244 => 24708,
18245 => 26725, 18246 => 30631, 18247 => 20052, 18248 => 20392, 18249 => 24039,
18250 => 38808, 18251 => 25772, 18252 => 32728, 18253 => 23789, 18254 => 20431,
18255 => 31373, 18256 => 20999, 18257 => 33540, 18258 => 19988, 18259 => 24623,
18260 => 31363, 18261 => 38054, 18262 => 20405, 18263 => 20146, 18264 => 31206,
18265 => 29748, 18266 => 21220, 18267 => 33465, 18268 => 25810, 18269 => 31165,
18270 => 23517, 18271 => 27777, 18272 => 38738, 18273 => 36731, 18274 => 27682,
18275 => 20542, 18276 => 21375, 18277 => 28165, 18278 => 25806, 18279 => 26228,
18280 => 27696, 18281 => 24773, 18282 => 39031, 18283 => 35831, 18284 => 24198,
18285 => 29756, 18286 => 31351, 18287 => 31179, 18288 => 19992, 18289 => 37041,
18290 => 29699, 18291 => 27714, 18292 => 22234, 18293 => 37195, 18294 => 27845,
18295 => 36235, 18296 => 21306, 18297 => 34502, 18298 => 26354, 18299 => 36527,
18300 => 23624, 18301 => 39537, 18302 => 28192, 18465 => 21462, 18466 => 23094,
18467 => 40843, 18468 => 36259, 18469 => 21435, 18470 => 22280, 18471 => 39079,
18472 => 26435, 18473 => 37275, 18474 => 27849, 18475 => 20840, 18476 => 30154,
18477 => 25331, 18478 => 29356, 18479 => 21048, 18480 => 21149, 18481 => 32570,
18482 => 28820, 18483 => 30264, 18484 => 21364, 18485 => 40522, 18486 => 27063,
18487 => 30830, 18488 => 38592, 18489 => 35033, 18490 => 32676, 18491 => 28982,
18492 => 29123, 18493 => 20873, 18494 => 26579, 18495 => 29924, 18496 => 22756,
18497 => 25880, 18498 => 22199, 18499 => 35753, 18500 => 39286, 18501 => 25200,
18502 => 32469, 18503 => 24825, 18504 => 28909, 18505 => 22764, 18506 => 20161,
18507 => 20154, 18508 => 24525, 18509 => 38887, 18510 => 20219, 18511 => 35748,
18512 => 20995, 18513 => 22922, 18514 => 32427, 18515 => 25172, 18516 => 20173,
18517 => 26085, 18518 => 25102, 18519 => 33592, 18520 => 33993, 18521 => 33635,
18522 => 34701, 18523 => 29076, 18524 => 28342, 18525 => 23481, 18526 => 32466,
18527 => 20887, 18528 => 25545, 18529 => 26580, 18530 => 32905, 18531 => 33593,
18532 => 34837, 18533 => 20754, 18534 => 23418, 18535 => 22914, 18536 => 36785,
18537 => 20083, 18538 => 27741, 18539 => 20837, 18540 => 35109, 18541 => 36719,
18542 => 38446, 18543 => 34122, 18544 => 29790, 18545 => 38160, 18546 => 38384,
18547 => 28070, 18548 => 33509, 18549 => 24369, 18550 => 25746, 18551 => 27922,
18552 => 33832, 18553 => 33134, 18554 => 40131, 18555 => 22622, 18556 => 36187,
18557 => 19977, 18558 => 21441, 18721 => 20254, 18722 => 25955, 18723 => 26705,
18724 => 21971, 18725 => 20007, 18726 => 25620, 18727 => 39578, 18728 => 25195,
18729 => 23234, 18730 => 29791, 18731 => 33394, 18732 => 28073, 18733 => 26862,
18734 => 20711, 18735 => 33678, 18736 => 30722, 18737 => 26432, 18738 => 21049,
18739 => 27801, 18740 => 32433, 18741 => 20667, 18742 => 21861, 18743 => 29022,
18744 => 31579, 18745 => 26194, 18746 => 29642, 18747 => 33515, 18748 => 26441,
18749 => 23665, 18750 => 21024, 18751 => 29053, 18752 => 34923, 18753 => 38378,
18754 => 38485, 18755 => 25797, 18756 => 36193, 18757 => 33203, 18758 => 21892,
18759 => 27733, 18760 => 25159, 18761 => 32558, 18762 => 22674, 18763 => 20260,
18764 => 21830, 18765 => 36175, 18766 => 26188, 18767 => 19978, 18768 => 23578,
18769 => 35059, 18770 => 26786, 18771 => 25422, 18772 => 31245, 18773 => 28903,
18774 => 33421, 18775 => 21242, 18776 => 38902, 18777 => 23569, 18778 => 21736,
18779 => 37045, 18780 => 32461, 18781 => 22882, 18782 => 36170, 18783 => 34503,
18784 => 33292, 18785 => 33293, 18786 => 36198, 18787 => 25668, 18788 => 23556,
18789 => 24913, 18790 => 28041, 18791 => 31038, 18792 => 35774, 18793 => 30775,
18794 => 30003, 18795 => 21627, 18796 => 20280, 18797 => 36523, 18798 => 28145,
18799 => 23072, 18800 => 32453, 18801 => 31070, 18802 => 27784, 18803 => 23457,
18804 => 23158, 18805 => 29978, 18806 => 32958, 18807 => 24910, 18808 => 28183,
18809 => 22768, 18810 => 29983, 18811 => 29989, 18812 => 29298, 18813 => 21319,
18814 => 32499, 18977 => 30465, 18978 => 30427, 18979 => 21097, 18980 => 32988,
18981 => 22307, 18982 => 24072, 18983 => 22833, 18984 => 29422, 18985 => 26045,
18986 => 28287, 18987 => 35799, 18988 => 23608, 18989 => 34417, 18990 => 21313,
18991 => 30707, 18992 => 25342, 18993 => 26102, 18994 => 20160, 18995 => 39135,
18996 => 34432, 18997 => 23454, 18998 => 35782, 18999 => 21490, 19000 => 30690,
19001 => 20351, 19002 => 23630, 19003 => 39542, 19004 => 22987, 19005 => 24335,
19006 => 31034, 19007 => 22763, 19008 => 19990, 19009 => 26623, 19010 => 20107,
19011 => 25325, 19012 => 35475, 19013 => 36893, 19014 => 21183, 19015 => 26159,
19016 => 21980, 19017 => 22124, 19018 => 36866, 19019 => 20181, 19020 => 20365,
19021 => 37322, 19022 => 39280, 19023 => 27663, 19024 => 24066, 19025 => 24643,
19026 => 23460, 19027 => 35270, 19028 => 35797, 19029 => 25910, 19030 => 25163,
19031 => 39318, 19032 => 23432, 19033 => 23551, 19034 => 25480, 19035 => 21806,
19036 => 21463, 19037 => 30246, 19038 => 20861, 19039 => 34092, 19040 => 26530,
19041 => 26803, 19042 => 27530, 19043 => 25234, 19044 => 36755, 19045 => 21460,
19046 => 33298, 19047 => 28113, 19048 => 30095, 19049 => 20070, 19050 => 36174,
19051 => 23408, 19052 => 29087, 19053 => 34223, 19054 => 26257, 19055 => 26329,
19056 => 32626, 19057 => 34560, 19058 => 40653, 19059 => 40736, 19060 => 23646,
19061 => 26415, 19062 => 36848, 19063 => 26641, 19064 => 26463, 19065 => 25101,
19066 => 31446, 19067 => 22661, 19068 => 24246, 19069 => 25968, 19070 => 28465,
19233 => 24661, 19234 => 21047, 19235 => 32781, 19236 => 25684, 19237 => 34928,
19238 => 29993, 19239 => 24069, 19240 => 26643, 19241 => 25332, 19242 => 38684,
19243 => 21452, 19244 => 29245, 19245 => 35841, 19246 => 27700, 19247 => 30561,
19248 => 31246, 19249 => 21550, 19250 => 30636, 19251 => 39034, 19252 => 33308,
19253 => 35828, 19254 => 30805, 19255 => 26388, 19256 => 28865, 19257 => 26031,
19258 => 25749, 19259 => 22070, 19260 => 24605, 19261 => 31169, 19262 => 21496,
19263 => 19997, 19264 => 27515, 19265 => 32902, 19266 => 23546, 19267 => 21987,
19268 => 22235, 19269 => 20282, 19270 => 20284, 19271 => 39282, 19272 => 24051,
19273 => 26494, 19274 => 32824, 19275 => 24578, 19276 => 39042, 19277 => 36865,
19278 => 23435, 19279 => 35772, 19280 => 35829, 19281 => 25628, 19282 => 33368,
19283 => 25822, 19284 => 22013, 19285 => 33487, 19286 => 37221, 19287 => 20439,
19288 => 32032, 19289 => 36895, 19290 => 31903, 19291 => 20723, 19292 => 22609,
19293 => 28335, 19294 => 23487, 19295 => 35785, 19296 => 32899, 19297 => 37240,
19298 => 33948, 19299 => 31639, 19300 => 34429, 19301 => 38539, 19302 => 38543,
19303 => 32485, 19304 => 39635, 19305 => 30862, 19306 => 23681, 19307 => 31319,
19308 => 36930, 19309 => 38567, 19310 => 31071, 19311 => 23385, 19312 => 25439,
19313 => 31499, 19314 => 34001, 19315 => 26797, 19316 => 21766, 19317 => 32553,
19318 => 29712, 19319 => 32034, 19320 => 38145, 19321 => 25152, 19322 => 22604,
19323 => 20182, 19324 => 23427, 19325 => 22905, 19326 => 22612, 19489 => 29549,
19490 => 25374, 19491 => 36427, 19492 => 36367, 19493 => 32974, 19494 => 33492,
19495 => 25260, 19496 => 21488, 19497 => 27888, 19498 => 37214, 19499 => 22826,
19500 => 24577, 19501 => 27760, 19502 => 22349, 19503 => 25674, 19504 => 36138,
19505 => 30251, 19506 => 28393, 19507 => 22363, 19508 => 27264, 19509 => 30192,
19510 => 28525, 19511 => 35885, 19512 => 35848, 19513 => 22374, 19514 => 27631,
19515 => 34962, 19516 => 30899, 19517 => 25506, 19518 => 21497, 19519 => 28845,
19520 => 27748, 19521 => 22616, 19522 => 25642, 19523 => 22530, 19524 => 26848,
19525 => 33179, 19526 => 21776, 19527 => 31958, 19528 => 20504, 19529 => 36538,
19530 => 28108, 19531 => 36255, 19532 => 28907, 19533 => 25487, 19534 => 28059,
19535 => 28372, 19536 => 32486, 19537 => 33796, 19538 => 26691, 19539 => 36867,
19540 => 28120, 19541 => 38518, 19542 => 35752, 19543 => 22871, 19544 => 29305,
19545 => 34276, 19546 => 33150, 19547 => 30140, 19548 => 35466, 19549 => 26799,
19550 => 21076, 19551 => 36386, 19552 => 38161, 19553 => 25552, 19554 => 39064,
19555 => 36420, 19556 => 21884, 19557 => 20307, 19558 => 26367, 19559 => 22159,
19560 => 24789, 19561 => 28053, 19562 => 21059, 19563 => 23625, 19564 => 22825,
19565 => 28155, 19566 => 22635, 19567 => 30000, 19568 => 29980, 19569 => 24684,
19570 => 33300, 19571 => 33094, 19572 => 25361, 19573 => 26465, 19574 => 36834,
19575 => 30522, 19576 => 36339, 19577 => 36148, 19578 => 38081, 19579 => 24086,
19580 => 21381, 19581 => 21548, 19582 => 28867, 19745 => 27712, 19746 => 24311,
19747 => 20572, 19748 => 20141, 19749 => 24237, 19750 => 25402, 19751 => 33351,
19752 => 36890, 19753 => 26704, 19754 => 37230, 19755 => 30643, 19756 => 21516,
19757 => 38108, 19758 => 24420, 19759 => 31461, 19760 => 26742, 19761 => 25413,
19762 => 31570, 19763 => 32479, 19764 => 30171, 19765 => 20599, 19766 => 25237,
19767 => 22836, 19768 => 36879, 19769 => 20984, 19770 => 31171, 19771 => 31361,
19772 => 22270, 19773 => 24466, 19774 => 36884, 19775 => 28034, 19776 => 23648,
19777 => 22303, 19778 => 21520, 19779 => 20820, 19780 => 28237, 19781 => 22242,
19782 => 25512, 19783 => 39059, 19784 => 33151, 19785 => 34581, 19786 => 35114,
19787 => 36864, 19788 => 21534, 19789 => 23663, 19790 => 33216, 19791 => 25302,
19792 => 25176, 19793 => 33073, 19794 => 40501, 19795 => 38464, 19796 => 39534,
19797 => 39548, 19798 => 26925, 19799 => 22949, 19800 => 25299, 19801 => 21822,
19802 => 25366, 19803 => 21703, 19804 => 34521, 19805 => 27964, 19806 => 23043,
19807 => 29926, 19808 => 34972, 19809 => 27498, 19810 => 22806, 19811 => 35916,
19812 => 24367, 19813 => 28286, 19814 => 29609, 19815 => 39037, 19816 => 20024,
19817 => 28919, 19818 => 23436, 19819 => 30871, 19820 => 25405, 19821 => 26202,
19822 => 30358, 19823 => 24779, 19824 => 23451, 19825 => 23113, 19826 => 19975,
19827 => 33109, 19828 => 27754, 19829 => 29579, 19830 => 20129, 19831 => 26505,
19832 => 32593, 19833 => 24448, 19834 => 26106, 19835 => 26395, 19836 => 24536,
19837 => 22916, 19838 => 23041, 20001 => 24013, 20002 => 24494, 20003 => 21361,
20004 => 38886, 20005 => 36829, 20006 => 26693, 20007 => 22260, 20008 => 21807,
20009 => 24799, 20010 => 20026, 20011 => 28493, 20012 => 32500, 20013 => 33479,
20014 => 33806, 20015 => 22996, 20016 => 20255, 20017 => 20266, 20018 => 23614,
20019 => 32428, 20020 => 26410, 20021 => 34074, 20022 => 21619, 20023 => 30031,
20024 => 32963, 20025 => 21890, 20026 => 39759, 20027 => 20301, 20028 => 28205,
20029 => 35859, 20030 => 23561, 20031 => 24944, 20032 => 21355, 20033 => 30239,
20034 => 28201, 20035 => 34442, 20036 => 25991, 20037 => 38395, 20038 => 32441,
20039 => 21563, 20040 => 31283, 20041 => 32010, 20042 => 38382, 20043 => 21985,
20044 => 32705, 20045 => 29934, 20046 => 25373, 20047 => 34583, 20048 => 28065,
20049 => 31389, 20050 => 25105, 20051 => 26017, 20052 => 21351, 20053 => 25569,
20054 => 27779, 20055 => 24043, 20056 => 21596, 20057 => 38056, 20058 => 20044,
20059 => 27745, 20060 => 35820, 20061 => 23627, 20062 => 26080, 20063 => 33436,
20064 => 26791, 20065 => 21566, 20066 => 21556, 20067 => 27595, 20068 => 27494,
20069 => 20116, 20070 => 25410, 20071 => 21320, 20072 => 33310, 20073 => 20237,
20074 => 20398, 20075 => 22366, 20076 => 25098, 20077 => 38654, 20078 => 26212,
20079 => 29289, 20080 => 21247, 20081 => 21153, 20082 => 24735, 20083 => 35823,
20084 => 26132, 20085 => 29081, 20086 => 26512, 20087 => 35199, 20088 => 30802,
20089 => 30717, 20090 => 26224, 20091 => 22075, 20092 => 21560, 20093 => 38177,
20094 => 29306, 20257 => 31232, 20258 => 24687, 20259 => 24076, 20260 => 24713,
20261 => 33181, 20262 => 22805, 20263 => 24796, 20264 => 29060, 20265 => 28911,
20266 => 28330, 20267 => 27728, 20268 => 29312, 20269 => 27268, 20270 => 34989,
20271 => 24109, 20272 => 20064, 20273 => 23219, 20274 => 21916, 20275 => 38115,
20276 => 27927, 20277 => 31995, 20278 => 38553, 20279 => 25103, 20280 => 32454,
20281 => 30606, 20282 => 34430, 20283 => 21283, 20284 => 38686, 20285 => 36758,
20286 => 26247, 20287 => 23777, 20288 => 20384, 20289 => 29421, 20290 => 19979,
20291 => 21414, 20292 => 22799, 20293 => 21523, 20294 => 25472, 20295 => 38184,
20296 => 20808, 20297 => 20185, 20298 => 40092, 20299 => 32420, 20300 => 21688,
20301 => 36132, 20302 => 34900, 20303 => 33335, 20304 => 38386, 20305 => 28046,
20306 => 24358, 20307 => 23244, 20308 => 26174, 20309 => 38505, 20310 => 29616,
20311 => 29486, 20312 => 21439, 20313 => 33146, 20314 => 39301, 20315 => 32673,
20316 => 23466, 20317 => 38519, 20318 => 38480, 20319 => 32447, 20320 => 30456,
20321 => 21410, 20322 => 38262, 20323 => 39321, 20324 => 31665, 20325 => 35140,
20326 => 28248, 20327 => 20065, 20328 => 32724, 20329 => 31077, 20330 => 35814,
20331 => 24819, 20332 => 21709, 20333 => 20139, 20334 => 39033, 20335 => 24055,
20336 => 27233, 20337 => 20687, 20338 => 21521, 20339 => 35937, 20340 => 33831,
20341 => 30813, 20342 => 38660, 20343 => 21066, 20344 => 21742, 20345 => 22179,
20346 => 38144, 20347 => 28040, 20348 => 23477, 20349 => 28102, 20350 => 26195,
20513 => 23567, 20514 => 23389, 20515 => 26657, 20516 => 32918, 20517 => 21880,
20518 => 31505, 20519 => 25928, 20520 => 26964, 20521 => 20123, 20522 => 27463,
20523 => 34638, 20524 => 38795, 20525 => 21327, 20526 => 25375, 20527 => 25658,
20528 => 37034, 20529 => 26012, 20530 => 32961, 20531 => 35856, 20532 => 20889,
20533 => 26800, 20534 => 21368, 20535 => 34809, 20536 => 25032, 20537 => 27844,
20538 => 27899, 20539 => 35874, 20540 => 23633, 20541 => 34218, 20542 => 33455,
20543 => 38156, 20544 => 27427, 20545 => 36763, 20546 => 26032, 20547 => 24571,
20548 => 24515, 20549 => 20449, 20550 => 34885, 20551 => 26143, 20552 => 33125,
20553 => 29481, 20554 => 24826, 20555 => 20852, 20556 => 21009, 20557 => 22411,
20558 => 24418, 20559 => 37026, 20560 => 34892, 20561 => 37266, 20562 => 24184,
20563 => 26447, 20564 => 24615, 20565 => 22995, 20566 => 20804, 20567 => 20982,
20568 => 33016, 20569 => 21256, 20570 => 27769, 20571 => 38596, 20572 => 29066,
20573 => 20241, 20574 => 20462, 20575 => 32670, 20576 => 26429, 20577 => 21957,
20578 => 38152, 20579 => 31168, 20580 => 34966, 20581 => 32483, 20582 => 22687,
20583 => 25100, 20584 => 38656, 20585 => 34394, 20586 => 22040, 20587 => 39035,
20588 => 24464, 20589 => 35768, 20590 => 33988, 20591 => 37207, 20592 => 21465,
20593 => 26093, 20594 => 24207, 20595 => 30044, 20596 => 24676, 20597 => 32110,
20598 => 23167, 20599 => 32490, 20600 => 32493, 20601 => 36713, 20602 => 21927,
20603 => 23459, 20604 => 24748, 20605 => 26059, 20606 => 29572, 20769 => 36873,
20770 => 30307, 20771 => 30505, 20772 => 32474, 20773 => 38772, 20774 => 34203,
20775 => 23398, 20776 => 31348, 20777 => 38634, 20778 => 34880, 20779 => 21195,
20780 => 29071, 20781 => 24490, 20782 => 26092, 20783 => 35810, 20784 => 23547,
20785 => 39535, 20786 => 24033, 20787 => 27529, 20788 => 27739, 20789 => 35757,
20790 => 35759, 20791 => 36874, 20792 => 36805, 20793 => 21387, 20794 => 25276,
20795 => 40486, 20796 => 40493, 20797 => 21568, 20798 => 20011, 20799 => 33469,
20800 => 29273, 20801 => 34460, 20802 => 23830, 20803 => 34905, 20804 => 28079,
20805 => 38597, 20806 => 21713, 20807 => 20122, 20808 => 35766, 20809 => 28937,
20810 => 21693, 20811 => 38409, 20812 => 28895, 20813 => 28153, 20814 => 30416,
20815 => 20005, 20816 => 30740, 20817 => 34578, 20818 => 23721, 20819 => 24310,
20820 => 35328, 20821 => 39068, 20822 => 38414, 20823 => 28814, 20824 => 27839,
20825 => 22852, 20826 => 25513, 20827 => 30524, 20828 => 34893, 20829 => 28436,
20830 => 33395, 20831 => 22576, 20832 => 29141, 20833 => 21388, 20834 => 30746,
20835 => 38593, 20836 => 21761, 20837 => 24422, 20838 => 28976, 20839 => 23476,
20840 => 35866, 20841 => 39564, 20842 => 27523, 20843 => 22830, 20844 => 40495,
20845 => 31207, 20846 => 26472, 20847 => 25196, 20848 => 20335, 20849 => 30113,
20850 => 32650, 20851 => 27915, 20852 => 38451, 20853 => 27687, 20854 => 20208,
20855 => 30162, 20856 => 20859, 20857 => 26679, 20858 => 28478, 20859 => 36992,
20860 => 33136, 20861 => 22934, 20862 => 29814, 21025 => 25671, 21026 => 23591,
21027 => 36965, 21028 => 31377, 21029 => 35875, 21030 => 23002, 21031 => 21676,
21032 => 33280, 21033 => 33647, 21034 => 35201, 21035 => 32768, 21036 => 26928,
21037 => 22094, 21038 => 32822, 21039 => 29239, 21040 => 37326, 21041 => 20918,
21042 => 20063, 21043 => 39029, 21044 => 25494, 21045 => 19994, 21046 => 21494,
21047 => 26355, 21048 => 33099, 21049 => 22812, 21050 => 28082, 21051 => 19968,
21052 => 22777, 21053 => 21307, 21054 => 25558, 21055 => 38129, 21056 => 20381,
21057 => 20234, 21058 => 34915, 21059 => 39056, 21060 => 22839, 21061 => 36951,
21062 => 31227, 21063 => 20202, 21064 => 33008, 21065 => 30097, 21066 => 27778,
21067 => 23452, 21068 => 23016, 21069 => 24413, 21070 => 26885, 21071 => 34433,
21072 => 20506, 21073 => 24050, 21074 => 20057, 21075 => 30691, 21076 => 20197,
21077 => 33402, 21078 => 25233, 21079 => 26131, 21080 => 37009, 21081 => 23673,
21082 => 20159, 21083 => 24441, 21084 => 33222, 21085 => 36920, 21086 => 32900,
21087 => 30123, 21088 => 20134, 21089 => 35028, 21090 => 24847, 21091 => 27589,
21092 => 24518, 21093 => 20041, 21094 => 30410, 21095 => 28322, 21096 => 35811,
21097 => 35758, 21098 => 35850, 21099 => 35793, 21100 => 24322, 21101 => 32764,
21102 => 32716, 21103 => 32462, 21104 => 33589, 21105 => 33643, 21106 => 22240,
21107 => 27575, 21108 => 38899, 21109 => 38452, 21110 => 23035, 21111 => 21535,
21112 => 38134, 21113 => 28139, 21114 => 23493, 21115 => 39278, 21116 => 23609,
21117 => 24341, 21118 => 38544, 21281 => 21360, 21282 => 33521, 21283 => 27185,
21284 => 23156, 21285 => 40560, 21286 => 24212, 21287 => 32552, 21288 => 33721,
21289 => 33828, 21290 => 33829, 21291 => 33639, 21292 => 34631, 21293 => 36814,
21294 => 36194, 21295 => 30408, 21296 => 24433, 21297 => 39062, 21298 => 30828,
21299 => 26144, 21300 => 21727, 21301 => 25317, 21302 => 20323, 21303 => 33219,
21304 => 30152, 21305 => 24248, 21306 => 38605, 21307 => 36362, 21308 => 34553,
21309 => 21647, 21310 => 27891, 21311 => 28044, 21312 => 27704, 21313 => 24703,
21314 => 21191, 21315 => 29992, 21316 => 24189, 21317 => 20248, 21318 => 24736,
21319 => 24551, 21320 => 23588, 21321 => 30001, 21322 => 37038, 21323 => 38080,
21324 => 29369, 21325 => 27833, 21326 => 28216, 21327 => 37193, 21328 => 26377,
21329 => 21451, 21330 => 21491, 21331 => 20305, 21332 => 37321, 21333 => 35825,
21334 => 21448, 21335 => 24188, 21336 => 36802, 21337 => 28132, 21338 => 20110,
21339 => 30402, 21340 => 27014, 21341 => 34398, 21342 => 24858, 21343 => 33286,
21344 => 20313, 21345 => 20446, 21346 => 36926, 21347 => 40060, 21348 => 24841,
21349 => 28189, 21350 => 28180, 21351 => 38533, 21352 => 20104, 21353 => 23089,
21354 => 38632, 21355 => 19982, 21356 => 23679, 21357 => 31161, 21358 => 23431,
21359 => 35821, 21360 => 32701, 21361 => 29577, 21362 => 22495, 21363 => 33419,
21364 => 37057, 21365 => 21505, 21366 => 36935, 21367 => 21947, 21368 => 23786,
21369 => 24481, 21370 => 24840, 21371 => 27442, 21372 => 29425, 21373 => 32946,
21374 => 35465, 21537 => 28020, 21538 => 23507, 21539 => 35029, 21540 => 39044,
21541 => 35947, 21542 => 39533, 21543 => 40499, 21544 => 28170, 21545 => 20900,
21546 => 20803, 21547 => 22435, 21548 => 34945, 21549 => 21407, 21550 => 25588,
21551 => 36757, 21552 => 22253, 21553 => 21592, 21554 => 22278, 21555 => 29503,
21556 => 28304, 21557 => 32536, 21558 => 36828, 21559 => 33489, 21560 => 24895,
21561 => 24616, 21562 => 38498, 21563 => 26352, 21564 => 32422, 21565 => 36234,
21566 => 36291, 21567 => 38053, 21568 => 23731, 21569 => 31908, 21570 => 26376,
21571 => 24742, 21572 => 38405, 21573 => 32792, 21574 => 20113, 21575 => 37095,
21576 => 21248, 21577 => 38504, 21578 => 20801, 21579 => 36816, 21580 => 34164,
21581 => 37213, 21582 => 26197, 21583 => 38901, 21584 => 23381, 21585 => 21277,
21586 => 30776, 21587 => 26434, 21588 => 26685, 21589 => 21705, 21590 => 28798,
21591 => 23472, 21592 => 36733, 21593 => 20877, 21594 => 22312, 21595 => 21681,
21596 => 25874, 21597 => 26242, 21598 => 36190, 21599 => 36163, 21600 => 33039,
21601 => 33900, 21602 => 36973, 21603 => 31967, 21604 => 20991, 21605 => 34299,
21606 => 26531, 21607 => 26089, 21608 => 28577, 21609 => 34468, 21610 => 36481,
21611 => 22122, 21612 => 36896, 21613 => 30338, 21614 => 28790, 21615 => 29157,
21616 => 36131, 21617 => 25321, 21618 => 21017, 21619 => 27901, 21620 => 36156,
21621 => 24590, 21622 => 22686, 21623 => 24974, 21624 => 26366, 21625 => 36192,
21626 => 25166, 21627 => 21939, 21628 => 28195, 21629 => 26413, 21630 => 36711,
21793 => 38113, 21794 => 38392, 21795 => 30504, 21796 => 26629, 21797 => 27048,
21798 => 21643, 21799 => 20045, 21800 => 28856, 21801 => 35784, 21802 => 25688,
21803 => 25995, 21804 => 23429, 21805 => 31364, 21806 => 20538, 21807 => 23528,
21808 => 30651, 21809 => 27617, 21810 => 35449, 21811 => 31896, 21812 => 27838,
21813 => 30415, 21814 => 26025, 21815 => 36759, 21816 => 23853, 21817 => 23637,
21818 => 34360, 21819 => 26632, 21820 => 21344, 21821 => 25112, 21822 => 31449,
21823 => 28251, 21824 => 32509, 21825 => 27167, 21826 => 31456, 21827 => 24432,
21828 => 28467, 21829 => 24352, 21830 => 25484, 21831 => 28072, 21832 => 26454,
21833 => 19976, 21834 => 24080, 21835 => 36134, 21836 => 20183, 21837 => 32960,
21838 => 30260, 21839 => 38556, 21840 => 25307, 21841 => 26157, 21842 => 25214,
21843 => 27836, 21844 => 36213, 21845 => 29031, 21846 => 32617, 21847 => 20806,
21848 => 32903, 21849 => 21484, 21850 => 36974, 21851 => 25240, 21852 => 21746,
21853 => 34544, 21854 => 36761, 21855 => 32773, 21856 => 38167, 21857 => 34071,
21858 => 36825, 21859 => 27993, 21860 => 29645, 21861 => 26015, 21862 => 30495,
21863 => 29956, 21864 => 30759, 21865 => 33275, 21866 => 36126, 21867 => 38024,
21868 => 20390, 21869 => 26517, 21870 => 30137, 21871 => 35786, 21872 => 38663,
21873 => 25391, 21874 => 38215, 21875 => 38453, 21876 => 33976, 21877 => 25379,
21878 => 30529, 21879 => 24449, 21880 => 29424, 21881 => 20105, 21882 => 24596,
21883 => 25972, 21884 => 25327, 21885 => 27491, 21886 => 25919, 22049 => 24103,
22050 => 30151, 22051 => 37073, 22052 => 35777, 22053 => 33437, 22054 => 26525,
22055 => 25903, 22056 => 21553, 22057 => 34584, 22058 => 30693, 22059 => 32930,
22060 => 33026, 22061 => 27713, 22062 => 20043, 22063 => 32455, 22064 => 32844,
22065 => 30452, 22066 => 26893, 22067 => 27542, 22068 => 25191, 22069 => 20540,
22070 => 20356, 22071 => 22336, 22072 => 25351, 22073 => 27490, 22074 => 36286,
22075 => 21482, 22076 => 26088, 22077 => 32440, 22078 => 24535, 22079 => 25370,
22080 => 25527, 22081 => 33267, 22082 => 33268, 22083 => 32622, 22084 => 24092,
22085 => 23769, 22086 => 21046, 22087 => 26234, 22088 => 31209, 22089 => 31258,
22090 => 36136, 22091 => 28825, 22092 => 30164, 22093 => 28382, 22094 => 27835,
22095 => 31378, 22096 => 20013, 22097 => 30405, 22098 => 24544, 22099 => 38047,
22100 => 34935, 22101 => 32456, 22102 => 31181, 22103 => 32959, 22104 => 37325,
22105 => 20210, 22106 => 20247, 22107 => 33311, 22108 => 21608, 22109 => 24030,
22110 => 27954, 22111 => 35788, 22112 => 31909, 22113 => 36724, 22114 => 32920,
22115 => 24090, 22116 => 21650, 22117 => 30385, 22118 => 23449, 22119 => 26172,
22120 => 39588, 22121 => 29664, 22122 => 26666, 22123 => 34523, 22124 => 26417,
22125 => 29482, 22126 => 35832, 22127 => 35803, 22128 => 36880, 22129 => 31481,
22130 => 28891, 22131 => 29038, 22132 => 25284, 22133 => 30633, 22134 => 22065,
22135 => 20027, 22136 => 33879, 22137 => 26609, 22138 => 21161, 22139 => 34496,
22140 => 36142, 22141 => 38136, 22142 => 31569, 22305 => 20303, 22306 => 27880,
22307 => 31069, 22308 => 39547, 22309 => 25235, 22310 => 29226, 22311 => 25341,
22312 => 19987, 22313 => 30742, 22314 => 36716, 22315 => 25776, 22316 => 36186,
22317 => 31686, 22318 => 26729, 22319 => 24196, 22320 => 35013, 22321 => 22918,
22322 => 25758, 22323 => 22766, 22324 => 29366, 22325 => 26894, 22326 => 38181,
22327 => 36861, 22328 => 36184, 22329 => 22368, 22330 => 32512, 22331 => 35846,
22332 => 20934, 22333 => 25417, 22334 => 25305, 22335 => 21331, 22336 => 26700,
22337 => 29730, 22338 => 33537, 22339 => 37196, 22340 => 21828, 22341 => 30528,
22342 => 28796, 22343 => 27978, 22344 => 20857, 22345 => 21672, 22346 => 36164,
22347 => 23039, 22348 => 28363, 22349 => 28100, 22350 => 23388, 22351 => 32043,
22352 => 20180, 22353 => 31869, 22354 => 28371, 22355 => 23376, 22356 => 33258,
22357 => 28173, 22358 => 23383, 22359 => 39683, 22360 => 26837, 22361 => 36394,
22362 => 23447, 22363 => 32508, 22364 => 24635, 22365 => 32437, 22366 => 37049,
22367 => 36208, 22368 => 22863, 22369 => 25549, 22370 => 31199, 22371 => 36275,
22372 => 21330, 22373 => 26063, 22374 => 31062, 22375 => 35781, 22376 => 38459,
22377 => 32452, 22378 => 38075, 22379 => 32386, 22380 => 22068, 22381 => 37257,
22382 => 26368, 22383 => 32618, 22384 => 23562, 22385 => 36981, 22386 => 26152,
22387 => 24038, 22388 => 20304, 22389 => 26590, 22390 => 20570, 22391 => 20316,
22392 => 22352, 22393 => 24231, 22561 => 20109, 22562 => 19980, 22563 => 20800,
22564 => 19984, 22565 => 24319, 22566 => 21317, 22567 => 19989, 22568 => 20120,
22569 => 19998, 22570 => 39730, 22571 => 23404, 22572 => 22121, 22573 => 20008,
22574 => 31162, 22575 => 20031, 22576 => 21269, 22577 => 20039, 22578 => 22829,
22579 => 29243, 22580 => 21358, 22581 => 27664, 22582 => 22239, 22583 => 32996,
22584 => 39319, 22585 => 27603, 22586 => 30590, 22587 => 40727, 22588 => 20022,
22589 => 20127, 22590 => 40720, 22591 => 20060, 22592 => 20073, 22593 => 20115,
22594 => 33416, 22595 => 23387, 22596 => 21868, 22597 => 22031, 22598 => 20164,
22599 => 21389, 22600 => 21405, 22601 => 21411, 22602 => 21413, 22603 => 21422,
22604 => 38757, 22605 => 36189, 22606 => 21274, 22607 => 21493, 22608 => 21286,
22609 => 21294, 22610 => 21310, 22611 => 36188, 22612 => 21350, 22613 => 21347,
22614 => 20994, 22615 => 21000, 22616 => 21006, 22617 => 21037, 22618 => 21043,
22619 => 21055, 22620 => 21056, 22621 => 21068, 22622 => 21086, 22623 => 21089,
22624 => 21084, 22625 => 33967, 22626 => 21117, 22627 => 21122, 22628 => 21121,
22629 => 21136, 22630 => 21139, 22631 => 20866, 22632 => 32596, 22633 => 20155,
22634 => 20163, 22635 => 20169, 22636 => 20162, 22637 => 20200, 22638 => 20193,
22639 => 20203, 22640 => 20190, 22641 => 20251, 22642 => 20211, 22643 => 20258,
22644 => 20324, 22645 => 20213, 22646 => 20261, 22647 => 20263, 22648 => 20233,
22649 => 20267, 22650 => 20318, 22651 => 20327, 22652 => 25912, 22653 => 20314,
22654 => 20317, 22817 => 20319, 22818 => 20311, 22819 => 20274, 22820 => 20285,
22821 => 20342, 22822 => 20340, 22823 => 20369, 22824 => 20361, 22825 => 20355,
22826 => 20367, 22827 => 20350, 22828 => 20347, 22829 => 20394, 22830 => 20348,
22831 => 20396, 22832 => 20372, 22833 => 20454, 22834 => 20456, 22835 => 20458,
22836 => 20421, 22837 => 20442, 22838 => 20451, 22839 => 20444, 22840 => 20433,
22841 => 20447, 22842 => 20472, 22843 => 20521, 22844 => 20556, 22845 => 20467,
22846 => 20524, 22847 => 20495, 22848 => 20526, 22849 => 20525, 22850 => 20478,
22851 => 20508, 22852 => 20492, 22853 => 20517, 22854 => 20520, 22855 => 20606,
22856 => 20547, 22857 => 20565, 22858 => 20552, 22859 => 20558, 22860 => 20588,
22861 => 20603, 22862 => 20645, 22863 => 20647, 22864 => 20649, 22865 => 20666,
22866 => 20694, 22867 => 20742, 22868 => 20717, 22869 => 20716, 22870 => 20710,
22871 => 20718, 22872 => 20743, 22873 => 20747, 22874 => 20189, 22875 => 27709,
22876 => 20312, 22877 => 20325, 22878 => 20430, 22879 => 40864, 22880 => 27718,
22881 => 31860, 22882 => 20846, 22883 => 24061, 22884 => 40649, 22885 => 39320,
22886 => 20865, 22887 => 22804, 22888 => 21241, 22889 => 21261, 22890 => 35335,
22891 => 21264, 22892 => 20971, 22893 => 22809, 22894 => 20821, 22895 => 20128,
22896 => 20822, 22897 => 20147, 22898 => 34926, 22899 => 34980, 22900 => 20149,
22901 => 33044, 22902 => 35026, 22903 => 31104, 22904 => 23348, 22905 => 34819,
22906 => 32696, 22907 => 20907, 22908 => 20913, 22909 => 20925, 22910 => 20924,
23073 => 20935, 23074 => 20886, 23075 => 20898, 23076 => 20901, 23077 => 35744,
23078 => 35750, 23079 => 35751, 23080 => 35754, 23081 => 35764, 23082 => 35765,
23083 => 35767, 23084 => 35778, 23085 => 35779, 23086 => 35787, 23087 => 35791,
23088 => 35790, 23089 => 35794, 23090 => 35795, 23091 => 35796, 23092 => 35798,
23093 => 35800, 23094 => 35801, 23095 => 35804, 23096 => 35807, 23097 => 35808,
23098 => 35812, 23099 => 35816, 23100 => 35817, 23101 => 35822, 23102 => 35824,
23103 => 35827, 23104 => 35830, 23105 => 35833, 23106 => 35836, 23107 => 35839,
23108 => 35840, 23109 => 35842, 23110 => 35844, 23111 => 35847, 23112 => 35852,
23113 => 35855, 23114 => 35857, 23115 => 35858, 23116 => 35860, 23117 => 35861,
23118 => 35862, 23119 => 35865, 23120 => 35867, 23121 => 35864, 23122 => 35869,
23123 => 35871, 23124 => 35872, 23125 => 35873, 23126 => 35877, 23127 => 35879,
23128 => 35882, 23129 => 35883, 23130 => 35886, 23131 => 35887, 23132 => 35890,
23133 => 35891, 23134 => 35893, 23135 => 35894, 23136 => 21353, 23137 => 21370,
23138 => 38429, 23139 => 38434, 23140 => 38433, 23141 => 38449, 23142 => 38442,
23143 => 38461, 23144 => 38460, 23145 => 38466, 23146 => 38473, 23147 => 38484,
23148 => 38495, 23149 => 38503, 23150 => 38508, 23151 => 38514, 23152 => 38516,
23153 => 38536, 23154 => 38541, 23155 => 38551, 23156 => 38576, 23157 => 37015,
23158 => 37019, 23159 => 37021, 23160 => 37017, 23161 => 37036, 23162 => 37025,
23163 => 37044, 23164 => 37043, 23165 => 37046, 23166 => 37050, 23329 => 37048,
23330 => 37040, 23331 => 37071, 23332 => 37061, 23333 => 37054, 23334 => 37072,
23335 => 37060, 23336 => 37063, 23337 => 37075, 23338 => 37094, 23339 => 37090,
23340 => 37084, 23341 => 37079, 23342 => 37083, 23343 => 37099, 23344 => 37103,
23345 => 37118, 23346 => 37124, 23347 => 37154, 23348 => 37150, 23349 => 37155,
23350 => 37169, 23351 => 37167, 23352 => 37177, 23353 => 37187, 23354 => 37190,
23355 => 21005, 23356 => 22850, 23357 => 21154, 23358 => 21164, 23359 => 21165,
23360 => 21182, 23361 => 21759, 23362 => 21200, 23363 => 21206, 23364 => 21232,
23365 => 21471, 23366 => 29166, 23367 => 30669, 23368 => 24308, 23369 => 20981,
23370 => 20988, 23371 => 39727, 23372 => 21430, 23373 => 24321, 23374 => 30042,
23375 => 24047, 23376 => 22348, 23377 => 22441, 23378 => 22433, 23379 => 22654,
23380 => 22716, 23381 => 22725, 23382 => 22737, 23383 => 22313, 23384 => 22316,
23385 => 22314, 23386 => 22323, 23387 => 22329, 23388 => 22318, 23389 => 22319,
23390 => 22364, 23391 => 22331, 23392 => 22338, 23393 => 22377, 23394 => 22405,
23395 => 22379, 23396 => 22406, 23397 => 22396, 23398 => 22395, 23399 => 22376,
23400 => 22381, 23401 => 22390, 23402 => 22387, 23403 => 22445, 23404 => 22436,
23405 => 22412, 23406 => 22450, 23407 => 22479, 23408 => 22439, 23409 => 22452,
23410 => 22419, 23411 => 22432, 23412 => 22485, 23413 => 22488, 23414 => 22490,
23415 => 22489, 23416 => 22482, 23417 => 22456, 23418 => 22516, 23419 => 22511,
23420 => 22520, 23421 => 22500, 23422 => 22493, 23585 => 22539, 23586 => 22541,
23587 => 22525, 23588 => 22509, 23589 => 22528, 23590 => 22558, 23591 => 22553,
23592 => 22596, 23593 => 22560, 23594 => 22629, 23595 => 22636, 23596 => 22657,
23597 => 22665, 23598 => 22682, 23599 => 22656, 23600 => 39336, 23601 => 40729,
23602 => 25087, 23603 => 33401, 23604 => 33405, 23605 => 33407, 23606 => 33423,
23607 => 33418, 23608 => 33448, 23609 => 33412, 23610 => 33422, 23611 => 33425,
23612 => 33431, 23613 => 33433, 23614 => 33451, 23615 => 33464, 23616 => 33470,
23617 => 33456, 23618 => 33480, 23619 => 33482, 23620 => 33507, 23621 => 33432,
23622 => 33463, 23623 => 33454, 23624 => 33483, 23625 => 33484, 23626 => 33473,
23627 => 33449, 23628 => 33460, 23629 => 33441, 23630 => 33450, 23631 => 33439,
23632 => 33476, 23633 => 33486, 23634 => 33444, 23635 => 33505, 23636 => 33545,
23637 => 33527, 23638 => 33508, 23639 => 33551, 23640 => 33543, 23641 => 33500,
23642 => 33524, 23643 => 33490, 23644 => 33496, 23645 => 33548, 23646 => 33531,
23647 => 33491, 23648 => 33553, 23649 => 33562, 23650 => 33542, 23651 => 33556,
23652 => 33557, 23653 => 33504, 23654 => 33493, 23655 => 33564, 23656 => 33617,
23657 => 33627, 23658 => 33628, 23659 => 33544, 23660 => 33682, 23661 => 33596,
23662 => 33588, 23663 => 33585, 23664 => 33691, 23665 => 33630, 23666 => 33583,
23667 => 33615, 23668 => 33607, 23669 => 33603, 23670 => 33631, 23671 => 33600,
23672 => 33559, 23673 => 33632, 23674 => 33581, 23675 => 33594, 23676 => 33587,
23677 => 33638, 23678 => 33637, 23841 => 33640, 23842 => 33563, 23843 => 33641,
23844 => 33644, 23845 => 33642, 23846 => 33645, 23847 => 33646, 23848 => 33712,
23849 => 33656, 23850 => 33715, 23851 => 33716, 23852 => 33696, 23853 => 33706,
23854 => 33683, 23855 => 33692, 23856 => 33669, 23857 => 33660, 23858 => 33718,
23859 => 33705, 23860 => 33661, 23861 => 33720, 23862 => 33659, 23863 => 33688,
23864 => 33694, 23865 => 33704, 23866 => 33722, 23867 => 33724, 23868 => 33729,
23869 => 33793, 23870 => 33765, 23871 => 33752, 23872 => 22535, 23873 => 33816,
23874 => 33803, 23875 => 33757, 23876 => 33789, 23877 => 33750, 23878 => 33820,
23879 => 33848, 23880 => 33809, 23881 => 33798, 23882 => 33748, 23883 => 33759,
23884 => 33807, 23885 => 33795, 23886 => 33784, 23887 => 33785, 23888 => 33770,
23889 => 33733, 23890 => 33728, 23891 => 33830, 23892 => 33776, 23893 => 33761,
23894 => 33884, 23895 => 33873, 23896 => 33882, 23897 => 33881, 23898 => 33907,
23899 => 33927, 23900 => 33928, 23901 => 33914, 23902 => 33929, 23903 => 33912,
23904 => 33852, 23905 => 33862, 23906 => 33897, 23907 => 33910, 23908 => 33932,
23909 => 33934, 23910 => 33841, 23911 => 33901, 23912 => 33985, 23913 => 33997,
23914 => 34000, 23915 => 34022, 23916 => 33981, 23917 => 34003, 23918 => 33994,
23919 => 33983, 23920 => 33978, 23921 => 34016, 23922 => 33953, 23923 => 33977,
23924 => 33972, 23925 => 33943, 23926 => 34021, 23927 => 34019, 23928 => 34060,
23929 => 29965, 23930 => 34104, 23931 => 34032, 23932 => 34105, 23933 => 34079,
23934 => 34106, 24097 => 34134, 24098 => 34107, 24099 => 34047, 24100 => 34044,
24101 => 34137, 24102 => 34120, 24103 => 34152, 24104 => 34148, 24105 => 34142,
24106 => 34170, 24107 => 30626, 24108 => 34115, 24109 => 34162, 24110 => 34171,
24111 => 34212, 24112 => 34216, 24113 => 34183, 24114 => 34191, 24115 => 34169,
24116 => 34222, 24117 => 34204, 24118 => 34181, 24119 => 34233, 24120 => 34231,
24121 => 34224, 24122 => 34259, 24123 => 34241, 24124 => 34268, 24125 => 34303,
24126 => 34343, 24127 => 34309, 24128 => 34345, 24129 => 34326, 24130 => 34364,
24131 => 24318, 24132 => 24328, 24133 => 22844, 24134 => 22849, 24135 => 32823,
24136 => 22869, 24137 => 22874, 24138 => 22872, 24139 => 21263, 24140 => 23586,
24141 => 23589, 24142 => 23596, 24143 => 23604, 24144 => 25164, 24145 => 25194,
24146 => 25247, 24147 => 25275, 24148 => 25290, 24149 => 25306, 24150 => 25303,
24151 => 25326, 24152 => 25378, 24153 => 25334, 24154 => 25401, 24155 => 25419,
24156 => 25411, 24157 => 25517, 24158 => 25590, 24159 => 25457, 24160 => 25466,
24161 => 25486, 24162 => 25524, 24163 => 25453, 24164 => 25516, 24165 => 25482,
24166 => 25449, 24167 => 25518, 24168 => 25532, 24169 => 25586, 24170 => 25592,
24171 => 25568, 24172 => 25599, 24173 => 25540, 24174 => 25566, 24175 => 25550,
24176 => 25682, 24177 => 25542, 24178 => 25534, 24179 => 25669, 24180 => 25665,
24181 => 25611, 24182 => 25627, 24183 => 25632, 24184 => 25612, 24185 => 25638,
24186 => 25633, 24187 => 25694, 24188 => 25732, 24189 => 25709, 24190 => 25750,
24353 => 25722, 24354 => 25783, 24355 => 25784, 24356 => 25753, 24357 => 25786,
24358 => 25792, 24359 => 25808, 24360 => 25815, 24361 => 25828, 24362 => 25826,
24363 => 25865, 24364 => 25893, 24365 => 25902, 24366 => 24331, 24367 => 24530,
24368 => 29977, 24369 => 24337, 24370 => 21343, 24371 => 21489, 24372 => 21501,
24373 => 21481, 24374 => 21480, 24375 => 21499, 24376 => 21522, 24377 => 21526,
24378 => 21510, 24379 => 21579, 24380 => 21586, 24381 => 21587, 24382 => 21588,
24383 => 21590, 24384 => 21571, 24385 => 21537, 24386 => 21591, 24387 => 21593,
24388 => 21539, 24389 => 21554, 24390 => 21634, 24391 => 21652, 24392 => 21623,
24393 => 21617, 24394 => 21604, 24395 => 21658, 24396 => 21659, 24397 => 21636,
24398 => 21622, 24399 => 21606, 24400 => 21661, 24401 => 21712, 24402 => 21677,
24403 => 21698, 24404 => 21684, 24405 => 21714, 24406 => 21671, 24407 => 21670,
24408 => 21715, 24409 => 21716, 24410 => 21618, 24411 => 21667, 24412 => 21717,
24413 => 21691, 24414 => 21695, 24415 => 21708, 24416 => 21721, 24417 => 21722,
24418 => 21724, 24419 => 21673, 24420 => 21674, 24421 => 21668, 24422 => 21725,
24423 => 21711, 24424 => 21726, 24425 => 21787, 24426 => 21735, 24427 => 21792,
24428 => 21757, 24429 => 21780, 24430 => 21747, 24431 => 21794, 24432 => 21795,
24433 => 21775, 24434 => 21777, 24435 => 21799, 24436 => 21802, 24437 => 21863,
24438 => 21903, 24439 => 21941, 24440 => 21833, 24441 => 21869, 24442 => 21825,
24443 => 21845, 24444 => 21823, 24445 => 21840, 24446 => 21820, 24609 => 21815,
24610 => 21846, 24611 => 21877, 24612 => 21878, 24613 => 21879, 24614 => 21811,
24615 => 21808, 24616 => 21852, 24617 => 21899, 24618 => 21970, 24619 => 21891,
24620 => 21937, 24621 => 21945, 24622 => 21896, 24623 => 21889, 24624 => 21919,
24625 => 21886, 24626 => 21974, 24627 => 21905, 24628 => 21883, 24629 => 21983,
24630 => 21949, 24631 => 21950, 24632 => 21908, 24633 => 21913, 24634 => 21994,
24635 => 22007, 24636 => 21961, 24637 => 22047, 24638 => 21969, 24639 => 21995,
24640 => 21996, 24641 => 21972, 24642 => 21990, 24643 => 21981, 24644 => 21956,
24645 => 21999, 24646 => 21989, 24647 => 22002, 24648 => 22003, 24649 => 21964,
24650 => 21965, 24651 => 21992, 24652 => 22005, 24653 => 21988, 24654 => 36756,
24655 => 22046, 24656 => 22024, 24657 => 22028, 24658 => 22017, 24659 => 22052,
24660 => 22051, 24661 => 22014, 24662 => 22016, 24663 => 22055, 24664 => 22061,
24665 => 22104, 24666 => 22073, 24667 => 22103, 24668 => 22060, 24669 => 22093,
24670 => 22114, 24671 => 22105, 24672 => 22108, 24673 => 22092, 24674 => 22100,
24675 => 22150, 24676 => 22116, 24677 => 22129, 24678 => 22123, 24679 => 22139,
24680 => 22140, 24681 => 22149, 24682 => 22163, 24683 => 22191, 24684 => 22228,
24685 => 22231, 24686 => 22237, 24687 => 22241, 24688 => 22261, 24689 => 22251,
24690 => 22265, 24691 => 22271, 24692 => 22276, 24693 => 22282, 24694 => 22281,
24695 => 22300, 24696 => 24079, 24697 => 24089, 24698 => 24084, 24699 => 24081,
24700 => 24113, 24701 => 24123, 24702 => 24124, 24865 => 24119, 24866 => 24132,
24867 => 24148, 24868 => 24155, 24869 => 24158, 24870 => 24161, 24871 => 23692,
24872 => 23674, 24873 => 23693, 24874 => 23696, 24875 => 23702, 24876 => 23688,
24877 => 23704, 24878 => 23705, 24879 => 23697, 24880 => 23706, 24881 => 23708,
24882 => 23733, 24883 => 23714, 24884 => 23741, 24885 => 23724, 24886 => 23723,
24887 => 23729, 24888 => 23715, 24889 => 23745, 24890 => 23735, 24891 => 23748,
24892 => 23762, 24893 => 23780, 24894 => 23755, 24895 => 23781, 24896 => 23810,
24897 => 23811, 24898 => 23847, 24899 => 23846, 24900 => 23854, 24901 => 23844,
24902 => 23838, 24903 => 23814, 24904 => 23835, 24905 => 23896, 24906 => 23870,
24907 => 23860, 24908 => 23869, 24909 => 23916, 24910 => 23899, 24911 => 23919,
24912 => 23901, 24913 => 23915, 24914 => 23883, 24915 => 23882, 24916 => 23913,
24917 => 23924, 24918 => 23938, 24919 => 23961, 24920 => 23965, 24921 => 35955,
24922 => 23991, 24923 => 24005, 24924 => 24435, 24925 => 24439, 24926 => 24450,
24927 => 24455, 24928 => 24457, 24929 => 24460, 24930 => 24469, 24931 => 24473,
24932 => 24476, 24933 => 24488, 24934 => 24493, 24935 => 24501, 24936 => 24508,
24937 => 34914, 24938 => 24417, 24939 => 29357, 24940 => 29360, 24941 => 29364,
24942 => 29367, 24943 => 29368, 24944 => 29379, 24945 => 29377, 24946 => 29390,
24947 => 29389, 24948 => 29394, 24949 => 29416, 24950 => 29423, 24951 => 29417,
24952 => 29426, 24953 => 29428, 24954 => 29431, 24955 => 29441, 24956 => 29427,
24957 => 29443, 24958 => 29434, 25121 => 29435, 25122 => 29463, 25123 => 29459,
25124 => 29473, 25125 => 29450, 25126 => 29470, 25127 => 29469, 25128 => 29461,
25129 => 29474, 25130 => 29497, 25131 => 29477, 25132 => 29484, 25133 => 29496,
25134 => 29489, 25135 => 29520, 25136 => 29517, 25137 => 29527, 25138 => 29536,
25139 => 29548, 25140 => 29551, 25141 => 29566, 25142 => 33307, 25143 => 22821,
25144 => 39143, 25145 => 22820, 25146 => 22786, 25147 => 39267, 25148 => 39271,
25149 => 39272, 25150 => 39273, 25151 => 39274, 25152 => 39275, 25153 => 39276,
25154 => 39284, 25155 => 39287, 25156 => 39293, 25157 => 39296, 25158 => 39300,
25159 => 39303, 25160 => 39306, 25161 => 39309, 25162 => 39312, 25163 => 39313,
25164 => 39315, 25165 => 39316, 25166 => 39317, 25167 => 24192, 25168 => 24209,
25169 => 24203, 25170 => 24214, 25171 => 24229, 25172 => 24224, 25173 => 24249,
25174 => 24245, 25175 => 24254, 25176 => 24243, 25177 => 36179, 25178 => 24274,
25179 => 24273, 25180 => 24283, 25181 => 24296, 25182 => 24298, 25183 => 33210,
25184 => 24516, 25185 => 24521, 25186 => 24534, 25187 => 24527, 25188 => 24579,
25189 => 24558, 25190 => 24580, 25191 => 24545, 25192 => 24548, 25193 => 24574,
25194 => 24581, 25195 => 24582, 25196 => 24554, 25197 => 24557, 25198 => 24568,
25199 => 24601, 25200 => 24629, 25201 => 24614, 25202 => 24603, 25203 => 24591,
25204 => 24589, 25205 => 24617, 25206 => 24619, 25207 => 24586, 25208 => 24639,
25209 => 24609, 25210 => 24696, 25211 => 24697, 25212 => 24699, 25213 => 24698,
25214 => 24642, 25377 => 24682, 25378 => 24701, 25379 => 24726, 25380 => 24730,
25381 => 24749, 25382 => 24733, 25383 => 24707, 25384 => 24722, 25385 => 24716,
25386 => 24731, 25387 => 24812, 25388 => 24763, 25389 => 24753, 25390 => 24797,
25391 => 24792, 25392 => 24774, 25393 => 24794, 25394 => 24756, 25395 => 24864,
25396 => 24870, 25397 => 24853, 25398 => 24867, 25399 => 24820, 25400 => 24832,
25401 => 24846, 25402 => 24875, 25403 => 24906, 25404 => 24949, 25405 => 25004,
25406 => 24980, 25407 => 24999, 25408 => 25015, 25409 => 25044, 25410 => 25077,
25411 => 24541, 25412 => 38579, 25413 => 38377, 25414 => 38379, 25415 => 38385,
25416 => 38387, 25417 => 38389, 25418 => 38390, 25419 => 38396, 25420 => 38398,
25421 => 38403, 25422 => 38404, 25423 => 38406, 25424 => 38408, 25425 => 38410,
25426 => 38411, 25427 => 38412, 25428 => 38413, 25429 => 38415, 25430 => 38418,
25431 => 38421, 25432 => 38422, 25433 => 38423, 25434 => 38425, 25435 => 38426,
25436 => 20012, 25437 => 29247, 25438 => 25109, 25439 => 27701, 25440 => 27732,
25441 => 27740, 25442 => 27722, 25443 => 27811, 25444 => 27781, 25445 => 27792,
25446 => 27796, 25447 => 27788, 25448 => 27752, 25449 => 27753, 25450 => 27764,
25451 => 27766, 25452 => 27782, 25453 => 27817, 25454 => 27856, 25455 => 27860,
25456 => 27821, 25457 => 27895, 25458 => 27896, 25459 => 27889, 25460 => 27863,
25461 => 27826, 25462 => 27872, 25463 => 27862, 25464 => 27898, 25465 => 27883,
25466 => 27886, 25467 => 27825, 25468 => 27859, 25469 => 27887, 25470 => 27902,
25633 => 27961, 25634 => 27943, 25635 => 27916, 25636 => 27971, 25637 => 27976,
25638 => 27911, 25639 => 27908, 25640 => 27929, 25641 => 27918, 25642 => 27947,
25643 => 27981, 25644 => 27950, 25645 => 27957, 25646 => 27930, 25647 => 27983,
25648 => 27986, 25649 => 27988, 25650 => 27955, 25651 => 28049, 25652 => 28015,
25653 => 28062, 25654 => 28064, 25655 => 27998, 25656 => 28051, 25657 => 28052,
25658 => 27996, 25659 => 28000, 25660 => 28028, 25661 => 28003, 25662 => 28186,
25663 => 28103, 25664 => 28101, 25665 => 28126, 25666 => 28174, 25667 => 28095,
25668 => 28128, 25669 => 28177, 25670 => 28134, 25671 => 28125, 25672 => 28121,
25673 => 28182, 25674 => 28075, 25675 => 28172, 25676 => 28078, 25677 => 28203,
25678 => 28270, 25679 => 28238, 25680 => 28267, 25681 => 28338, 25682 => 28255,
25683 => 28294, 25684 => 28243, 25685 => 28244, 25686 => 28210, 25687 => 28197,
25688 => 28228, 25689 => 28383, 25690 => 28337, 25691 => 28312, 25692 => 28384,
25693 => 28461, 25694 => 28386, 25695 => 28325, 25696 => 28327, 25697 => 28349,
25698 => 28347, 25699 => 28343, 25700 => 28375, 25701 => 28340, 25702 => 28367,
25703 => 28303, 25704 => 28354, 25705 => 28319, 25706 => 28514, 25707 => 28486,
25708 => 28487, 25709 => 28452, 25710 => 28437, 25711 => 28409, 25712 => 28463,
25713 => 28470, 25714 => 28491, 25715 => 28532, 25716 => 28458, 25717 => 28425,
25718 => 28457, 25719 => 28553, 25720 => 28557, 25721 => 28556, 25722 => 28536,
25723 => 28530, 25724 => 28540, 25725 => 28538, 25726 => 28625, 25889 => 28617,
25890 => 28583, 25891 => 28601, 25892 => 28598, 25893 => 28610, 25894 => 28641,
25895 => 28654, 25896 => 28638, 25897 => 28640, 25898 => 28655, 25899 => 28698,
25900 => 28707, 25901 => 28699, 25902 => 28729, 25903 => 28725, 25904 => 28751,
25905 => 28766, 25906 => 23424, 25907 => 23428, 25908 => 23445, 25909 => 23443,
25910 => 23461, 25911 => 23480, 25912 => 29999, 25913 => 39582, 25914 => 25652,
25915 => 23524, 25916 => 23534, 25917 => 35120, 25918 => 23536, 25919 => 36423,
25920 => 35591, 25921 => 36790, 25922 => 36819, 25923 => 36821, 25924 => 36837,
25925 => 36846, 25926 => 36836, 25927 => 36841, 25928 => 36838, 25929 => 36851,
25930 => 36840, 25931 => 36869, 25932 => 36868, 25933 => 36875, 25934 => 36902,
25935 => 36881, 25936 => 36877, 25937 => 36886, 25938 => 36897, 25939 => 36917,
25940 => 36918, 25941 => 36909, 25942 => 36911, 25943 => 36932, 25944 => 36945,
25945 => 36946, 25946 => 36944, 25947 => 36968, 25948 => 36952, 25949 => 36962,
25950 => 36955, 25951 => 26297, 25952 => 36980, 25953 => 36989, 25954 => 36994,
25955 => 37000, 25956 => 36995, 25957 => 37003, 25958 => 24400, 25959 => 24407,
25960 => 24406, 25961 => 24408, 25962 => 23611, 25963 => 21675, 25964 => 23632,
25965 => 23641, 25966 => 23409, 25967 => 23651, 25968 => 23654, 25969 => 32700,
25970 => 24362, 25971 => 24361, 25972 => 24365, 25973 => 33396, 25974 => 24380,
25975 => 39739, 25976 => 23662, 25977 => 22913, 25978 => 22915, 25979 => 22925,
25980 => 22953, 25981 => 22954, 25982 => 22947, 26145 => 22935, 26146 => 22986,
26147 => 22955, 26148 => 22942, 26149 => 22948, 26150 => 22994, 26151 => 22962,
26152 => 22959, 26153 => 22999, 26154 => 22974, 26155 => 23045, 26156 => 23046,
26157 => 23005, 26158 => 23048, 26159 => 23011, 26160 => 23000, 26161 => 23033,
26162 => 23052, 26163 => 23049, 26164 => 23090, 26165 => 23092, 26166 => 23057,
26167 => 23075, 26168 => 23059, 26169 => 23104, 26170 => 23143, 26171 => 23114,
26172 => 23125, 26173 => 23100, 26174 => 23138, 26175 => 23157, 26176 => 33004,
26177 => 23210, 26178 => 23195, 26179 => 23159, 26180 => 23162, 26181 => 23230,
26182 => 23275, 26183 => 23218, 26184 => 23250, 26185 => 23252, 26186 => 23224,
26187 => 23264, 26188 => 23267, 26189 => 23281, 26190 => 23254, 26191 => 23270,
26192 => 23256, 26193 => 23260, 26194 => 23305, 26195 => 23319, 26196 => 23318,
26197 => 23346, 26198 => 23351, 26199 => 23360, 26200 => 23573, 26201 => 23580,
26202 => 23386, 26203 => 23397, 26204 => 23411, 26205 => 23377, 26206 => 23379,
26207 => 23394, 26208 => 39541, 26209 => 39543, 26210 => 39544, 26211 => 39546,
26212 => 39551, 26213 => 39549, 26214 => 39552, 26215 => 39553, 26216 => 39557,
26217 => 39560, 26218 => 39562, 26219 => 39568, 26220 => 39570, 26221 => 39571,
26222 => 39574, 26223 => 39576, 26224 => 39579, 26225 => 39580, 26226 => 39581,
26227 => 39583, 26228 => 39584, 26229 => 39586, 26230 => 39587, 26231 => 39589,
26232 => 39591, 26233 => 32415, 26234 => 32417, 26235 => 32419, 26236 => 32421,
26237 => 32424, 26238 => 32425, 26401 => 32429, 26402 => 32432, 26403 => 32446,
26404 => 32448, 26405 => 32449, 26406 => 32450, 26407 => 32457, 26408 => 32459,
26409 => 32460, 26410 => 32464, 26411 => 32468, 26412 => 32471, 26413 => 32475,
26414 => 32480, 26415 => 32481, 26416 => 32488, 26417 => 32491, 26418 => 32494,
26419 => 32495, 26420 => 32497, 26421 => 32498, 26422 => 32525, 26423 => 32502,
26424 => 32506, 26425 => 32507, 26426 => 32510, 26427 => 32513, 26428 => 32514,
26429 => 32515, 26430 => 32519, 26431 => 32520, 26432 => 32523, 26433 => 32524,
26434 => 32527, 26435 => 32529, 26436 => 32530, 26437 => 32535, 26438 => 32537,
26439 => 32540, 26440 => 32539, 26441 => 32543, 26442 => 32545, 26443 => 32546,
26444 => 32547, 26445 => 32548, 26446 => 32549, 26447 => 32550, 26448 => 32551,
26449 => 32554, 26450 => 32555, 26451 => 32556, 26452 => 32557, 26453 => 32559,
26454 => 32560, 26455 => 32561, 26456 => 32562, 26457 => 32563, 26458 => 32565,
26459 => 24186, 26460 => 30079, 26461 => 24027, 26462 => 30014, 26463 => 37013,
26464 => 29582, 26465 => 29585, 26466 => 29614, 26467 => 29602, 26468 => 29599,
26469 => 29647, 26470 => 29634, 26471 => 29649, 26472 => 29623, 26473 => 29619,
26474 => 29632, 26475 => 29641, 26476 => 29640, 26477 => 29669, 26478 => 29657,
26479 => 39036, 26480 => 29706, 26481 => 29673, 26482 => 29671, 26483 => 29662,
26484 => 29626, 26485 => 29682, 26486 => 29711, 26487 => 29738, 26488 => 29787,
26489 => 29734, 26490 => 29733, 26491 => 29736, 26492 => 29744, 26493 => 29742,
26494 => 29740, 26657 => 29723, 26658 => 29722, 26659 => 29761, 26660 => 29788,
26661 => 29783, 26662 => 29781, 26663 => 29785, 26664 => 29815, 26665 => 29805,
26666 => 29822, 26667 => 29852, 26668 => 29838, 26669 => 29824, 26670 => 29825,
26671 => 29831, 26672 => 29835, 26673 => 29854, 26674 => 29864, 26675 => 29865,
26676 => 29840, 26677 => 29863, 26678 => 29906, 26679 => 29882, 26680 => 38890,
26681 => 38891, 26682 => 38892, 26683 => 26444, 26684 => 26451, 26685 => 26462,
26686 => 26440, 26687 => 26473, 26688 => 26533, 26689 => 26503, 26690 => 26474,
26691 => 26483, 26692 => 26520, 26693 => 26535, 26694 => 26485, 26695 => 26536,
26696 => 26526, 26697 => 26541, 26698 => 26507, 26699 => 26487, 26700 => 26492,
26701 => 26608, 26702 => 26633, 26703 => 26584, 26704 => 26634, 26705 => 26601,
26706 => 26544, 26707 => 26636, 26708 => 26585, 26709 => 26549, 26710 => 26586,
26711 => 26547, 26712 => 26589, 26713 => 26624, 26714 => 26563, 26715 => 26552,
26716 => 26594, 26717 => 26638, 26718 => 26561, 26719 => 26621, 26720 => 26674,
26721 => 26675, 26722 => 26720, 26723 => 26721, 26724 => 26702, 26725 => 26722,
26726 => 26692, 26727 => 26724, 26728 => 26755, 26729 => 26653, 26730 => 26709,
26731 => 26726, 26732 => 26689, 26733 => 26727, 26734 => 26688, 26735 => 26686,
26736 => 26698, 26737 => 26697, 26738 => 26665, 26739 => 26805, 26740 => 26767,
26741 => 26740, 26742 => 26743, 26743 => 26771, 26744 => 26731, 26745 => 26818,
26746 => 26990, 26747 => 26876, 26748 => 26911, 26749 => 26912, 26750 => 26873,
26913 => 26916, 26914 => 26864, 26915 => 26891, 26916 => 26881, 26917 => 26967,
26918 => 26851, 26919 => 26896, 26920 => 26993, 26921 => 26937, 26922 => 26976,
26923 => 26946, 26924 => 26973, 26925 => 27012, 26926 => 26987, 26927 => 27008,
26928 => 27032, 26929 => 27000, 26930 => 26932, 26931 => 27084, 26932 => 27015,
26933 => 27016, 26934 => 27086, 26935 => 27017, 26936 => 26982, 26937 => 26979,
26938 => 27001, 26939 => 27035, 26940 => 27047, 26941 => 27067, 26942 => 27051,
26943 => 27053, 26944 => 27092, 26945 => 27057, 26946 => 27073, 26947 => 27082,
26948 => 27103, 26949 => 27029, 26950 => 27104, 26951 => 27021, 26952 => 27135,
26953 => 27183, 26954 => 27117, 26955 => 27159, 26956 => 27160, 26957 => 27237,
26958 => 27122, 26959 => 27204, 26960 => 27198, 26961 => 27296, 26962 => 27216,
26963 => 27227, 26964 => 27189, 26965 => 27278, 26966 => 27257, 26967 => 27197,
26968 => 27176, 26969 => 27224, 26970 => 27260, 26971 => 27281, 26972 => 27280,
26973 => 27305, 26974 => 27287, 26975 => 27307, 26976 => 29495, 26977 => 29522,
26978 => 27521, 26979 => 27522, 26980 => 27527, 26981 => 27524, 26982 => 27538,
26983 => 27539, 26984 => 27533, 26985 => 27546, 26986 => 27547, 26987 => 27553,
26988 => 27562, 26989 => 36715, 26990 => 36717, 26991 => 36721, 26992 => 36722,
26993 => 36723, 26994 => 36725, 26995 => 36726, 26996 => 36728, 26997 => 36727,
26998 => 36729, 26999 => 36730, 27000 => 36732, 27001 => 36734, 27002 => 36737,
27003 => 36738, 27004 => 36740, 27005 => 36743, 27006 => 36747, 27169 => 36749,
27170 => 36750, 27171 => 36751, 27172 => 36760, 27173 => 36762, 27174 => 36558,
27175 => 25099, 27176 => 25111, 27177 => 25115, 27178 => 25119, 27179 => 25122,
27180 => 25121, 27181 => 25125, 27182 => 25124, 27183 => 25132, 27184 => 33255,
27185 => 29935, 27186 => 29940, 27187 => 29951, 27188 => 29967, 27189 => 29969,
27190 => 29971, 27191 => 25908, 27192 => 26094, 27193 => 26095, 27194 => 26096,
27195 => 26122, 27196 => 26137, 27197 => 26482, 27198 => 26115, 27199 => 26133,
27200 => 26112, 27201 => 28805, 27202 => 26359, 27203 => 26141, 27204 => 26164,
27205 => 26161, 27206 => 26166, 27207 => 26165, 27208 => 32774, 27209 => 26207,
27210 => 26196, 27211 => 26177, 27212 => 26191, 27213 => 26198, 27214 => 26209,
27215 => 26199, 27216 => 26231, 27217 => 26244, 27218 => 26252, 27219 => 26279,
27220 => 26269, 27221 => 26302, 27222 => 26331, 27223 => 26332, 27224 => 26342,
27225 => 26345, 27226 => 36146, 27227 => 36147, 27228 => 36150, 27229 => 36155,
27230 => 36157, 27231 => 36160, 27232 => 36165, 27233 => 36166, 27234 => 36168,
27235 => 36169, 27236 => 36167, 27237 => 36173, 27238 => 36181, 27239 => 36185,
27240 => 35271, 27241 => 35274, 27242 => 35275, 27243 => 35276, 27244 => 35278,
27245 => 35279, 27246 => 35280, 27247 => 35281, 27248 => 29294, 27249 => 29343,
27250 => 29277, 27251 => 29286, 27252 => 29295, 27253 => 29310, 27254 => 29311,
27255 => 29316, 27256 => 29323, 27257 => 29325, 27258 => 29327, 27259 => 29330,
27260 => 25352, 27261 => 25394, 27262 => 25520, 27425 => 25663, 27426 => 25816,
27427 => 32772, 27428 => 27626, 27429 => 27635, 27430 => 27645, 27431 => 27637,
27432 => 27641, 27433 => 27653, 27434 => 27655, 27435 => 27654, 27436 => 27661,
27437 => 27669, 27438 => 27672, 27439 => 27673, 27440 => 27674, 27441 => 27681,
27442 => 27689, 27443 => 27684, 27444 => 27690, 27445 => 27698, 27446 => 25909,
27447 => 25941, 27448 => 25963, 27449 => 29261, 27450 => 29266, 27451 => 29270,
27452 => 29232, 27453 => 34402, 27454 => 21014, 27455 => 32927, 27456 => 32924,
27457 => 32915, 27458 => 32956, 27459 => 26378, 27460 => 32957, 27461 => 32945,
27462 => 32939, 27463 => 32941, 27464 => 32948, 27465 => 32951, 27466 => 32999,
27467 => 33000, 27468 => 33001, 27469 => 33002, 27470 => 32987, 27471 => 32962,
27472 => 32964, 27473 => 32985, 27474 => 32973, 27475 => 32983, 27476 => 26384,
27477 => 32989, 27478 => 33003, 27479 => 33009, 27480 => 33012, 27481 => 33005,
27482 => 33037, 27483 => 33038, 27484 => 33010, 27485 => 33020, 27486 => 26389,
27487 => 33042, 27488 => 35930, 27489 => 33078, 27490 => 33054, 27491 => 33068,
27492 => 33048, 27493 => 33074, 27494 => 33096, 27495 => 33100, 27496 => 33107,
27497 => 33140, 27498 => 33113, 27499 => 33114, 27500 => 33137, 27501 => 33120,
27502 => 33129, 27503 => 33148, 27504 => 33149, 27505 => 33133, 27506 => 33127,
27507 => 22605, 27508 => 23221, 27509 => 33160, 27510 => 33154, 27511 => 33169,
27512 => 28373, 27513 => 33187, 27514 => 33194, 27515 => 33228, 27516 => 26406,
27517 => 33226, 27518 => 33211, 27681 => 33217, 27682 => 33190, 27683 => 27428,
27684 => 27447, 27685 => 27449, 27686 => 27459, 27687 => 27462, 27688 => 27481,
27689 => 39121, 27690 => 39122, 27691 => 39123, 27692 => 39125, 27693 => 39129,
27694 => 39130, 27695 => 27571, 27696 => 24384, 27697 => 27586, 27698 => 35315,
27699 => 26000, 27700 => 40785, 27701 => 26003, 27702 => 26044, 27703 => 26054,
27704 => 26052, 27705 => 26051, 27706 => 26060, 27707 => 26062, 27708 => 26066,
27709 => 26070, 27710 => 28800, 27711 => 28828, 27712 => 28822, 27713 => 28829,
27714 => 28859, 27715 => 28864, 27716 => 28855, 27717 => 28843, 27718 => 28849,
27719 => 28904, 27720 => 28874, 27721 => 28944, 27722 => 28947, 27723 => 28950,
27724 => 28975, 27725 => 28977, 27726 => 29043, 27727 => 29020, 27728 => 29032,
27729 => 28997, 27730 => 29042, 27731 => 29002, 27732 => 29048, 27733 => 29050,
27734 => 29080, 27735 => 29107, 27736 => 29109, 27737 => 29096, 27738 => 29088,
27739 => 29152, 27740 => 29140, 27741 => 29159, 27742 => 29177, 27743 => 29213,
27744 => 29224, 27745 => 28780, 27746 => 28952, 27747 => 29030, 27748 => 29113,
27749 => 25150, 27750 => 25149, 27751 => 25155, 27752 => 25160, 27753 => 25161,
27754 => 31035, 27755 => 31040, 27756 => 31046, 27757 => 31049, 27758 => 31067,
27759 => 31068, 27760 => 31059, 27761 => 31066, 27762 => 31074, 27763 => 31063,
27764 => 31072, 27765 => 31087, 27766 => 31079, 27767 => 31098, 27768 => 31109,
27769 => 31114, 27770 => 31130, 27771 => 31143, 27772 => 31155, 27773 => 24529,
27774 => 24528, 27937 => 24636, 27938 => 24669, 27939 => 24666, 27940 => 24679,
27941 => 24641, 27942 => 24665, 27943 => 24675, 27944 => 24747, 27945 => 24838,
27946 => 24845, 27947 => 24925, 27948 => 25001, 27949 => 24989, 27950 => 25035,
27951 => 25041, 27952 => 25094, 27953 => 32896, 27954 => 32895, 27955 => 27795,
27956 => 27894, 27957 => 28156, 27958 => 30710, 27959 => 30712, 27960 => 30720,
27961 => 30729, 27962 => 30743, 27963 => 30744, 27964 => 30737, 27965 => 26027,
27966 => 30765, 27967 => 30748, 27968 => 30749, 27969 => 30777, 27970 => 30778,
27971 => 30779, 27972 => 30751, 27973 => 30780, 27974 => 30757, 27975 => 30764,
27976 => 30755, 27977 => 30761, 27978 => 30798, 27979 => 30829, 27980 => 30806,
27981 => 30807, 27982 => 30758, 27983 => 30800, 27984 => 30791, 27985 => 30796,
27986 => 30826, 27987 => 30875, 27988 => 30867, 27989 => 30874, 27990 => 30855,
27991 => 30876, 27992 => 30881, 27993 => 30883, 27994 => 30898, 27995 => 30905,
27996 => 30885, 27997 => 30932, 27998 => 30937, 27999 => 30921, 28000 => 30956,
28001 => 30962, 28002 => 30981, 28003 => 30964, 28004 => 30995, 28005 => 31012,
28006 => 31006, 28007 => 31028, 28008 => 40859, 28009 => 40697, 28010 => 40699,
28011 => 40700, 28012 => 30449, 28013 => 30468, 28014 => 30477, 28015 => 30457,
28016 => 30471, 28017 => 30472, 28018 => 30490, 28019 => 30498, 28020 => 30489,
28021 => 30509, 28022 => 30502, 28023 => 30517, 28024 => 30520, 28025 => 30544,
28026 => 30545, 28027 => 30535, 28028 => 30531, 28029 => 30554, 28030 => 30568,
28193 => 30562, 28194 => 30565, 28195 => 30591, 28196 => 30605, 28197 => 30589,
28198 => 30592, 28199 => 30604, 28200 => 30609, 28201 => 30623, 28202 => 30624,
28203 => 30640, 28204 => 30645, 28205 => 30653, 28206 => 30010, 28207 => 30016,
28208 => 30030, 28209 => 30027, 28210 => 30024, 28211 => 30043, 28212 => 30066,
28213 => 30073, 28214 => 30083, 28215 => 32600, 28216 => 32609, 28217 => 32607,
28218 => 35400, 28219 => 32616, 28220 => 32628, 28221 => 32625, 28222 => 32633,
28223 => 32641, 28224 => 32638, 28225 => 30413, 28226 => 30437, 28227 => 34866,
28228 => 38021, 28229 => 38022, 28230 => 38023, 28231 => 38027, 28232 => 38026,
28233 => 38028, 28234 => 38029, 28235 => 38031, 28236 => 38032, 28237 => 38036,
28238 => 38039, 28239 => 38037, 28240 => 38042, 28241 => 38043, 28242 => 38044,
28243 => 38051, 28244 => 38052, 28245 => 38059, 28246 => 38058, 28247 => 38061,
28248 => 38060, 28249 => 38063, 28250 => 38064, 28251 => 38066, 28252 => 38068,
28253 => 38070, 28254 => 38071, 28255 => 38072, 28256 => 38073, 28257 => 38074,
28258 => 38076, 28259 => 38077, 28260 => 38079, 28261 => 38084, 28262 => 38088,
28263 => 38089, 28264 => 38090, 28265 => 38091, 28266 => 38092, 28267 => 38093,
28268 => 38094, 28269 => 38096, 28270 => 38097, 28271 => 38098, 28272 => 38101,
28273 => 38102, 28274 => 38103, 28275 => 38105, 28276 => 38104, 28277 => 38107,
28278 => 38110, 28279 => 38111, 28280 => 38112, 28281 => 38114, 28282 => 38116,
28283 => 38117, 28284 => 38119, 28285 => 38120, 28286 => 38122, 28449 => 38121,
28450 => 38123, 28451 => 38126, 28452 => 38127, 28453 => 38131, 28454 => 38132,
28455 => 38133, 28456 => 38135, 28457 => 38137, 28458 => 38140, 28459 => 38141,
28460 => 38143, 28461 => 38147, 28462 => 38146, 28463 => 38150, 28464 => 38151,
28465 => 38153, 28466 => 38154, 28467 => 38157, 28468 => 38158, 28469 => 38159,
28470 => 38162, 28471 => 38163, 28472 => 38164, 28473 => 38165, 28474 => 38166,
28475 => 38168, 28476 => 38171, 28477 => 38173, 28478 => 38174, 28479 => 38175,
28480 => 38178, 28481 => 38186, 28482 => 38187, 28483 => 38185, 28484 => 38188,
28485 => 38193, 28486 => 38194, 28487 => 38196, 28488 => 38198, 28489 => 38199,
28490 => 38200, 28491 => 38204, 28492 => 38206, 28493 => 38207, 28494 => 38210,
28495 => 38197, 28496 => 38212, 28497 => 38213, 28498 => 38214, 28499 => 38217,
28500 => 38220, 28501 => 38222, 28502 => 38223, 28503 => 38226, 28504 => 38227,
28505 => 38228, 28506 => 38230, 28507 => 38231, 28508 => 38232, 28509 => 38233,
28510 => 38235, 28511 => 38238, 28512 => 38239, 28513 => 38237, 28514 => 38241,
28515 => 38242, 28516 => 38244, 28517 => 38245, 28518 => 38246, 28519 => 38247,
28520 => 38248, 28521 => 38249, 28522 => 38250, 28523 => 38251, 28524 => 38252,
28525 => 38255, 28526 => 38257, 28527 => 38258, 28528 => 38259, 28529 => 38202,
28530 => 30695, 28531 => 30700, 28532 => 38601, 28533 => 31189, 28534 => 31213,
28535 => 31203, 28536 => 31211, 28537 => 31238, 28538 => 23879, 28539 => 31235,
28540 => 31234, 28541 => 31262, 28542 => 31252, 28705 => 31289, 28706 => 31287,
28707 => 31313, 28708 => 40655, 28709 => 39333, 28710 => 31344, 28711 => 30344,
28712 => 30350, 28713 => 30355, 28714 => 30361, 28715 => 30372, 28716 => 29918,
28717 => 29920, 28718 => 29996, 28719 => 40480, 28720 => 40482, 28721 => 40488,
28722 => 40489, 28723 => 40490, 28724 => 40491, 28725 => 40492, 28726 => 40498,
28727 => 40497, 28728 => 40502, 28729 => 40504, 28730 => 40503, 28731 => 40505,
28732 => 40506, 28733 => 40510, 28734 => 40513, 28735 => 40514, 28736 => 40516,
28737 => 40518, 28738 => 40519, 28739 => 40520, 28740 => 40521, 28741 => 40523,
28742 => 40524, 28743 => 40526, 28744 => 40529, 28745 => 40533, 28746 => 40535,
28747 => 40538, 28748 => 40539, 28749 => 40540, 28750 => 40542, 28751 => 40547,
28752 => 40550, 28753 => 40551, 28754 => 40552, 28755 => 40553, 28756 => 40554,
28757 => 40555, 28758 => 40556, 28759 => 40561, 28760 => 40557, 28761 => 40563,
28762 => 30098, 28763 => 30100, 28764 => 30102, 28765 => 30112, 28766 => 30109,
28767 => 30124, 28768 => 30115, 28769 => 30131, 28770 => 30132, 28771 => 30136,
28772 => 30148, 28773 => 30129, 28774 => 30128, 28775 => 30147, 28776 => 30146,
28777 => 30166, 28778 => 30157, 28779 => 30179, 28780 => 30184, 28781 => 30182,
28782 => 30180, 28783 => 30187, 28784 => 30183, 28785 => 30211, 28786 => 30193,
28787 => 30204, 28788 => 30207, 28789 => 30224, 28790 => 30208, 28791 => 30213,
28792 => 30220, 28793 => 30231, 28794 => 30218, 28795 => 30245, 28796 => 30232,
28797 => 30229, 28798 => 30233, 28961 => 30235, 28962 => 30268, 28963 => 30242,
28964 => 30240, 28965 => 30272, 28966 => 30253, 28967 => 30256, 28968 => 30271,
28969 => 30261, 28970 => 30275, 28971 => 30270, 28972 => 30259, 28973 => 30285,
28974 => 30302, 28975 => 30292, 28976 => 30300, 28977 => 30294, 28978 => 30315,
28979 => 30319, 28980 => 32714, 28981 => 31462, 28982 => 31352, 28983 => 31353,
28984 => 31360, 28985 => 31366, 28986 => 31368, 28987 => 31381, 28988 => 31398,
28989 => 31392, 28990 => 31404, 28991 => 31400, 28992 => 31405, 28993 => 31411,
28994 => 34916, 28995 => 34921, 28996 => 34930, 28997 => 34941, 28998 => 34943,
28999 => 34946, 29000 => 34978, 29001 => 35014, 29002 => 34999, 29003 => 35004,
29004 => 35017, 29005 => 35042, 29006 => 35022, 29007 => 35043, 29008 => 35045,
29009 => 35057, 29010 => 35098, 29011 => 35068, 29012 => 35048, 29013 => 35070,
29014 => 35056, 29015 => 35105, 29016 => 35097, 29017 => 35091, 29018 => 35099,
29019 => 35082, 29020 => 35124, 29021 => 35115, 29022 => 35126, 29023 => 35137,
29024 => 35174, 29025 => 35195, 29026 => 30091, 29027 => 32997, 29028 => 30386,
29029 => 30388, 29030 => 30684, 29031 => 32786, 29032 => 32788, 29033 => 32790,
29034 => 32796, 29035 => 32800, 29036 => 32802, 29037 => 32805, 29038 => 32806,
29039 => 32807, 29040 => 32809, 29041 => 32808, 29042 => 32817, 29043 => 32779,
29044 => 32821, 29045 => 32835, 29046 => 32838, 29047 => 32845, 29048 => 32850,
29049 => 32873, 29050 => 32881, 29051 => 35203, 29052 => 39032, 29053 => 39040,
29054 => 39043, 29217 => 39049, 29218 => 39052, 29219 => 39053, 29220 => 39055,
29221 => 39060, 29222 => 39066, 29223 => 39067, 29224 => 39070, 29225 => 39071,
29226 => 39073, 29227 => 39074, 29228 => 39077, 29229 => 39078, 29230 => 34381,
29231 => 34388, 29232 => 34412, 29233 => 34414, 29234 => 34431, 29235 => 34426,
29236 => 34428, 29237 => 34427, 29238 => 34472, 29239 => 34445, 29240 => 34443,
29241 => 34476, 29242 => 34461, 29243 => 34471, 29244 => 34467, 29245 => 34474,
29246 => 34451, 29247 => 34473, 29248 => 34486, 29249 => 34500, 29250 => 34485,
29251 => 34510, 29252 => 34480, 29253 => 34490, 29254 => 34481, 29255 => 34479,
29256 => 34505, 29257 => 34511, 29258 => 34484, 29259 => 34537, 29260 => 34545,
29261 => 34546, 29262 => 34541, 29263 => 34547, 29264 => 34512, 29265 => 34579,
29266 => 34526, 29267 => 34548, 29268 => 34527, 29269 => 34520, 29270 => 34513,
29271 => 34563, 29272 => 34567, 29273 => 34552, 29274 => 34568, 29275 => 34570,
29276 => 34573, 29277 => 34569, 29278 => 34595, 29279 => 34619, 29280 => 34590,
29281 => 34597, 29282 => 34606, 29283 => 34586, 29284 => 34622, 29285 => 34632,
29286 => 34612, 29287 => 34609, 29288 => 34601, 29289 => 34615, 29290 => 34623,
29291 => 34690, 29292 => 34594, 29293 => 34685, 29294 => 34686, 29295 => 34683,
29296 => 34656, 29297 => 34672, 29298 => 34636, 29299 => 34670, 29300 => 34699,
29301 => 34643, 29302 => 34659, 29303 => 34684, 29304 => 34660, 29305 => 34649,
29306 => 34661, 29307 => 34707, 29308 => 34735, 29309 => 34728, 29310 => 34770,
29473 => 34758, 29474 => 34696, 29475 => 34693, 29476 => 34733, 29477 => 34711,
29478 => 34691, 29479 => 34731, 29480 => 34789, 29481 => 34732, 29482 => 34741,
29483 => 34739, 29484 => 34763, 29485 => 34771, 29486 => 34749, 29487 => 34769,
29488 => 34752, 29489 => 34762, 29490 => 34779, 29491 => 34794, 29492 => 34784,
29493 => 34798, 29494 => 34838, 29495 => 34835, 29496 => 34814, 29497 => 34826,
29498 => 34843, 29499 => 34849, 29500 => 34873, 29501 => 34876, 29502 => 32566,
29503 => 32578, 29504 => 32580, 29505 => 32581, 29506 => 33296, 29507 => 31482,
29508 => 31485, 29509 => 31496, 29510 => 31491, 29511 => 31492, 29512 => 31509,
29513 => 31498, 29514 => 31531, 29515 => 31503, 29516 => 31559, 29517 => 31544,
29518 => 31530, 29519 => 31513, 29520 => 31534, 29521 => 31537, 29522 => 31520,
29523 => 31525, 29524 => 31524, 29525 => 31539, 29526 => 31550, 29527 => 31518,
29528 => 31576, 29529 => 31578, 29530 => 31557, 29531 => 31605, 29532 => 31564,
29533 => 31581, 29534 => 31584, 29535 => 31598, 29536 => 31611, 29537 => 31586,
29538 => 31602, 29539 => 31601, 29540 => 31632, 29541 => 31654, 29542 => 31655,
29543 => 31672, 29544 => 31660, 29545 => 31645, 29546 => 31656, 29547 => 31621,
29548 => 31658, 29549 => 31644, 29550 => 31650, 29551 => 31659, 29552 => 31668,
29553 => 31697, 29554 => 31681, 29555 => 31692, 29556 => 31709, 29557 => 31706,
29558 => 31717, 29559 => 31718, 29560 => 31722, 29561 => 31756, 29562 => 31742,
29563 => 31740, 29564 => 31759, 29565 => 31766, 29566 => 31755, 29729 => 31775,
29730 => 31786, 29731 => 31782, 29732 => 31800, 29733 => 31809, 29734 => 31808,
29735 => 33278, 29736 => 33281, 29737 => 33282, 29738 => 33284, 29739 => 33260,
29740 => 34884, 29741 => 33313, 29742 => 33314, 29743 => 33315, 29744 => 33325,
29745 => 33327, 29746 => 33320, 29747 => 33323, 29748 => 33336, 29749 => 33339,
29750 => 33331, 29751 => 33332, 29752 => 33342, 29753 => 33348, 29754 => 33353,
29755 => 33355, 29756 => 33359, 29757 => 33370, 29758 => 33375, 29759 => 33384,
29760 => 34942, 29761 => 34949, 29762 => 34952, 29763 => 35032, 29764 => 35039,
29765 => 35166, 29766 => 32669, 29767 => 32671, 29768 => 32679, 29769 => 32687,
29770 => 32688, 29771 => 32690, 29772 => 31868, 29773 => 25929, 29774 => 31889,
29775 => 31901, 29776 => 31900, 29777 => 31902, 29778 => 31906, 29779 => 31922,
29780 => 31932, 29781 => 31933, 29782 => 31937, 29783 => 31943, 29784 => 31948,
29785 => 31949, 29786 => 31944, 29787 => 31941, 29788 => 31959, 29789 => 31976,
29790 => 33390, 29791 => 26280, 29792 => 32703, 29793 => 32718, 29794 => 32725,
29795 => 32741, 29796 => 32737, 29797 => 32742, 29798 => 32745, 29799 => 32750,
29800 => 32755, 29801 => 31992, 29802 => 32119, 29803 => 32166, 29804 => 32174,
29805 => 32327, 29806 => 32411, 29807 => 40632, 29808 => 40628, 29809 => 36211,
29810 => 36228, 29811 => 36244, 29812 => 36241, 29813 => 36273, 29814 => 36199,
29815 => 36205, 29816 => 35911, 29817 => 35913, 29818 => 37194, 29819 => 37200,
29820 => 37198, 29821 => 37199, 29822 => 37220, 29985 => 37218, 29986 => 37217,
29987 => 37232, 29988 => 37225, 29989 => 37231, 29990 => 37245, 29991 => 37246,
29992 => 37234, 29993 => 37236, 29994 => 37241, 29995 => 37260, 29996 => 37253,
29997 => 37264, 29998 => 37261, 29999 => 37265, 30000 => 37282, 30001 => 37283,
30002 => 37290, 30003 => 37293, 30004 => 37294, 30005 => 37295, 30006 => 37301,
30007 => 37300, 30008 => 37306, 30009 => 35925, 30010 => 40574, 30011 => 36280,
30012 => 36331, 30013 => 36357, 30014 => 36441, 30015 => 36457, 30016 => 36277,
30017 => 36287, 30018 => 36284, 30019 => 36282, 30020 => 36292, 30021 => 36310,
30022 => 36311, 30023 => 36314, 30024 => 36318, 30025 => 36302, 30026 => 36303,
30027 => 36315, 30028 => 36294, 30029 => 36332, 30030 => 36343, 30031 => 36344,
30032 => 36323, 30033 => 36345, 30034 => 36347, 30035 => 36324, 30036 => 36361,
30037 => 36349, 30038 => 36372, 30039 => 36381, 30040 => 36383, 30041 => 36396,
30042 => 36398, 30043 => 36387, 30044 => 36399, 30045 => 36410, 30046 => 36416,
30047 => 36409, 30048 => 36405, 30049 => 36413, 30050 => 36401, 30051 => 36425,
30052 => 36417, 30053 => 36418, 30054 => 36433, 30055 => 36434, 30056 => 36426,
30057 => 36464, 30058 => 36470, 30059 => 36476, 30060 => 36463, 30061 => 36468,
30062 => 36485, 30063 => 36495, 30064 => 36500, 30065 => 36496, 30066 => 36508,
30067 => 36510, 30068 => 35960, 30069 => 35970, 30070 => 35978, 30071 => 35973,
30072 => 35992, 30073 => 35988, 30074 => 26011, 30075 => 35286, 30076 => 35294,
30077 => 35290, 30078 => 35292, 30241 => 35301, 30242 => 35307, 30243 => 35311,
30244 => 35390, 30245 => 35622, 30246 => 38739, 30247 => 38633, 30248 => 38643,
30249 => 38639, 30250 => 38662, 30251 => 38657, 30252 => 38664, 30253 => 38671,
30254 => 38670, 30255 => 38698, 30256 => 38701, 30257 => 38704, 30258 => 38718,
30259 => 40832, 30260 => 40835, 30261 => 40837, 30262 => 40838, 30263 => 40839,
30264 => 40840, 30265 => 40841, 30266 => 40842, 30267 => 40844, 30268 => 40702,
30269 => 40715, 30270 => 40717, 30271 => 38585, 30272 => 38588, 30273 => 38589,
30274 => 38606, 30275 => 38610, 30276 => 30655, 30277 => 38624, 30278 => 37518,
30279 => 37550, 30280 => 37576, 30281 => 37694, 30282 => 37738, 30283 => 37834,
30284 => 37775, 30285 => 37950, 30286 => 37995, 30287 => 40063, 30288 => 40066,
30289 => 40069, 30290 => 40070, 30291 => 40071, 30292 => 40072, 30293 => 31267,
30294 => 40075, 30295 => 40078, 30296 => 40080, 30297 => 40081, 30298 => 40082,
30299 => 40084, 30300 => 40085, 30301 => 40090, 30302 => 40091, 30303 => 40094,
30304 => 40095, 30305 => 40096, 30306 => 40097, 30307 => 40098, 30308 => 40099,
30309 => 40101, 30310 => 40102, 30311 => 40103, 30312 => 40104, 30313 => 40105,
30314 => 40107, 30315 => 40109, 30316 => 40110, 30317 => 40112, 30318 => 40113,
30319 => 40114, 30320 => 40115, 30321 => 40116, 30322 => 40117, 30323 => 40118,
30324 => 40119, 30325 => 40122, 30326 => 40123, 30327 => 40124, 30328 => 40125,
30329 => 40132, 30330 => 40133, 30331 => 40134, 30332 => 40135, 30333 => 40138,
30334 => 40139, 30497 => 40140, 30498 => 40141, 30499 => 40142, 30500 => 40143,
30501 => 40144, 30502 => 40147, 30503 => 40148, 30504 => 40149, 30505 => 40151,
30506 => 40152, 30507 => 40153, 30508 => 40156, 30509 => 40157, 30510 => 40159,
30511 => 40162, 30512 => 38780, 30513 => 38789, 30514 => 38801, 30515 => 38802,
30516 => 38804, 30517 => 38831, 30518 => 38827, 30519 => 38819, 30520 => 38834,
30521 => 38836, 30522 => 39601, 30523 => 39600, 30524 => 39607, 30525 => 40536,
30526 => 39606, 30527 => 39610, 30528 => 39612, 30529 => 39617, 30530 => 39616,
30531 => 39621, 30532 => 39618, 30533 => 39627, 30534 => 39628, 30535 => 39633,
30536 => 39749, 30537 => 39747, 30538 => 39751, 30539 => 39753, 30540 => 39752,
30541 => 39757, 30542 => 39761, 30543 => 39144, 30544 => 39181, 30545 => 39214,
30546 => 39253, 30547 => 39252, 30548 => 39647, 30549 => 39649, 30550 => 39654,
30551 => 39663, 30552 => 39659, 30553 => 39675, 30554 => 39661, 30555 => 39673,
30556 => 39688, 30557 => 39695, 30558 => 39699, 30559 => 39711, 30560 => 39715,
30561 => 40637, 30562 => 40638, 30563 => 32315, 30564 => 40578, 30565 => 40583,
30566 => 40584, 30567 => 40587, 30568 => 40594, 30569 => 37846, 30570 => 40605,
30571 => 40607, 30572 => 40667, 30573 => 40668, 30574 => 40669, 30575 => 40672,
30576 => 40671, 30577 => 40674, 30578 => 40681, 30579 => 40679, 30580 => 40677,
30581 => 40682, 30582 => 40687, 30583 => 40738, 30584 => 40748, 30585 => 40751,
30586 => 40761, 30587 => 40759, 30588 => 40765, 30589 => 40766, 30590 => 40772,
0 => 0 );
 
function gb2utf8($gb) {
if( !trim($gb) ) return $gb;
$utf8='';
while($gb) {
if( ord(substr($gb,0,1)) > 127 ) {
$t=substr($gb,0,2);
$gb=substr($gb,2);
$utf8 .= $this->u2utf8($this->codetable[hexdec(bin2hex($t))-0x8080]);
}
else {
$t=substr($gb,0,1);
$gb=substr($gb,1);
$utf8 .= $this->u2utf8($t);
}
}
return $utf8;
}
function u2utf8($c) {
$str='';
if ($c < 0x80) {
$str.=$c;
}
else if ($c < 0x800) {
$str.=chr(0xC0 | $c>>6);
$str.=chr(0x80 | $c & 0x3F);
}
else if ($c < 0x10000) {
$str.=chr(0xE0 | $c>>12);
$str.=chr(0x80 | $c>>6 & 0x3F);
$str.=chr(0x80 | $c & 0x3F);
}
else if ($c < 0x200000) {
$str.=chr(0xF0 | $c>>18);
$str.=chr(0x80 | $c>>12 & 0x3F);
$str.=chr(0x80 | $c>>6 & 0x3F);
$str.=chr(0x80 | $c & 0x3F);
}
return $str;
}
 
} // END Class
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_plotmark.inc.php
New file
0,0 → 1,496
<?php
//=======================================================================
// File: JPGRAPH_PLOTMARK.PHP
// Description: Class file. Handles plotmarks
// Created: 2003-03-21
// Ver: $Id: jpgraph_plotmark.inc.php 955 2007-11-17 11:41:42Z 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::RaiseL(23001,$this->name,$aIdx); //('This marker "'.($this->name).'" does not exist in color: '.$aIdx);
}
$idx = $this->index[$aIdx];
}
elseif( !is_integer($aIdx) ||
(is_integer($aIdx) && $aIdx > $this->maxidx ) ) {
JpGraphError::RaiseL(23002,$this->name);
//('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='',$csimwintarget='',$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->type=-1;
}
//---------------
// PUBLIC METHODS
function SetType($aType,$aFileName='',$aScale=1.0) {
$this->type = $aType;
if( $aType == MARK_IMG && $aFileName=='' ) {
JpGraphError::RaiseL(23003);//('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,$aWinTarget='') {
$this->csimtarget=$aTarget;
$this->csimwintarget=$aWinTarget;
}
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=\"".htmlentities($this->csimtarget)."\"";
 
if( !empty($this->csimwintarget) ) {
$this->csimareas .= " target=\"".$this->csimwintarget."\" ";
}
 
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\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=\"".htmlentities($this->csimtarget)."\"";
 
if( !empty($this->csimwintarget) ) {
$this->csimareas .= " target=\"".$this->csimwintarget."\" ";
}
 
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\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.php';
$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.php';
$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.php';
$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.php';
$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.php';
$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.php';
$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=\"".htmlentities($this->csimtarget)."\"";
if( !empty($this->csimwintarget) ) {
$this->csimareas .= " target=\"".$this->csimwintarget."\" ";
}
 
if( !empty($this->csimalt) ) {
$tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" ";
}
$this->csimareas .= " />\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
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/imgdata_bevels.inc.php
New file
0,0 → 1,104
<?php
//=======================================================================
// File: IMGDATA_BEVELS.INC
// Description: Base64 encoded images for round bevels
// Created: 2003-03-20
// Ver: $Id: imgdata_bevels.inc.php 859 2007-03-23 19:12:08Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
class ImgData_Bevels extends ImgData {
var $name = 'Round Bevels';
var $an = array(MARK_IMG_BEVEL => 'imgdata');
var $colors = array('green','purple','orange','red','yellow');
var $index = array('green'=>1,'purple'=>4,'orange'=>2,'red'=>0,'yellow'=>3);
var $maxidx = 4 ;
 
var $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==' ;
 
}
}
 
 
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_scatter.php
New file
0,0 → 1,228
<?php
/*=======================================================================
// File: JPGRAPH_SCATTER.PHP
// Description: Scatter (and impuls) plot extension for JpGraph
// Created: 2001-02-11
// Ver: $Id: jpgraph_scatter.php 955 2007-11-17 11:41:42Z 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 {
var $iSize=10; // Length in pixels for arrow
var $iArrowSize = 2;
var $iColor='black';
var $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 {
var $iAngles;
var $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;
$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,$this->legendcsimwintarget);
}
}
}
 
//===================================================
// CLASS ScatterPlot
// Description: Render X and Y plots
//===================================================
class ScatterPlot extends Plot {
var $impuls = false;
var $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]) ) {
if( !empty($this->csimwintargets[$i]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$i],$this->csimwintargets[$i]);
}
else {
$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,$this->legendcsimwintarget);
}
}
} // Class
/* EOF */
?>
/obs_saisons/SPIP-v1-8-3/modules/bibliotheque/jpgraph/jpgraph_ttf.inc.php
New file
0,0 → 1,379
<?php
//=======================================================================
// File: jpgraph_ttf.inc.php
// Description: Handling of TTF fonts
// Created: 2006-11-19
// Ver: $Id: jpgraph_ttf.inc.php 1080 2008-09-19 16:06:46Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
 
// TTF Font families
DEFINE("FF_COURIER",10);
DEFINE("FF_VERDANA",11);
DEFINE("FF_TIMES",12);
DEFINE("FF_COMIC",14);
DEFINE("FF_ARIAL",15);
DEFINE("FF_GEORGIA",16);
DEFINE("FF_TREBUCHE",17);
 
// Gnome Vera font
// Available from http://www.gnome.org/fonts/
DEFINE("FF_VERA",19);
DEFINE("FF_VERAMONO",20);
DEFINE("FF_VERASERIF",21);
 
// Chinese font
DEFINE("FF_SIMSUN",30);
DEFINE("FF_CHINESE",31);
DEFINE("FF_BIG5",31);
 
// Japanese font
DEFINE("FF_MINCHO",40);
DEFINE("FF_PMINCHO",41);
DEFINE("FF_GOTHIC",42);
DEFINE("FF_PGOTHIC",43);
 
// Hebrew fonts
DEFINE("FF_DAVID",44);
DEFINE("FF_MIRIAM",45);
DEFINE("FF_AHRON",46);
 
// Dejavu-fonts http://sourceforge.net/projects/dejavu
DEFINE("FF_DV_SANSSERIF",47);
DEFINE("FF_DV_SERIF",48);
DEFINE("FF_DV_SANSSERIFMONO",49);
DEFINE("FF_DV_SERIFCOND",50);
DEFINE("FF_DV_SANSSERIFCOND",51);
 
// Extra fonts
// Download fonts from
// http://www.webfontlist.com
// http://www.webpagepublicity.com/free-fonts.html
 
DEFINE("FF_SPEEDO",50); // This font is also known as Bauer (Used for gauge fascia)
DEFINE("FF_DIGITAL",51); // Digital readout font
DEFINE("FF_COMPUTER",52); // The classic computer font
DEFINE("FF_CALCULATOR",53); // Triad font
 
// Limits for TTF fonts
DEFINE('_FF_FIRST',10);
DEFINE('_FF_LAST',53);
 
// Older deprecated fonts
DEFINE("FF_BOOK",91); // Deprecated fonts from 1.9
DEFINE("FF_HANDWRT",92); // Deprecated fonts from 1.9
 
// TTF Font styles
DEFINE("FS_NORMAL",9001);
DEFINE("FS_BOLD",9002);
DEFINE("FS_ITALIC",9003);
DEFINE("FS_BOLDIT",9004);
DEFINE("FS_BOLDITALIC",9004);
 
//Definitions for internal font
DEFINE("FF_FONT0",1);
DEFINE("FF_FONT1",2);
DEFINE("FF_FONT2",4);
 
 
//===================================================
// CLASS LanguageConv
// Description:
// Converts variouscharacter encoding into proper
// UTF-8 depending on how the library have been configured.
//===================================================
class LanguageConv {
var $g2312 = null ;
 
function Convert($aTxt,$aFF) {
if( LANGUAGE_GREEK ) {
if( GREEK_FROM_WINDOWS ) {
$unistring = LanguageConv::gr_win2uni($aTxt);
} else {
$unistring = LanguageConv::gr_iso2uni($aTxt);
}
return $unistring;
} elseif( LANGUAGE_CYRILLIC ) {
if( CYRILLIC_FROM_WINDOWS && (!defined('CYRILLIC_LANGUAGE_CHARSET') || stristr(CYRILLIC_LANGUAGE_CHARSET, 'windows-1251')) ) {
$aTxt = convert_cyr_string($aTxt, "w", "k");
}
if( !defined('CYRILLIC_LANGUAGE_CHARSET') || stristr(CYRILLIC_LANGUAGE_CHARSET, 'koi8-r') || stristr(CYRILLIC_LANGUAGE_CHARSET, 'windows-1251')) {
$isostring = convert_cyr_string($aTxt, "k", "i");
$unistring = LanguageConv::iso2uni($isostring);
}
else {
$unistring = $aTxt;
}
return $unistring;
}
elseif( $aFF === FF_SIMSUN ) {
// Do Chinese conversion
if( $this->g2312 == null ) {
include_once 'jpgraph_gb2312.php' ;
$this->g2312 = new GB2312toUTF8();
}
return $this->g2312->gb2utf8($aTxt);
}
elseif( $aFF === FF_CHINESE ) {
if( !function_exists('iconv') ) {
JpGraphError::RaiseL(25006);
//('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).');
}
return iconv('BIG5','UTF-8',$aTxt);
}
elseif( ASSUME_EUCJP_ENCODING &&
($aFF == FF_MINCHO || $aFF == FF_GOTHIC || $aFF == FF_PMINCHO || $aFF == FF_PGOTHIC) ) {
if( !function_exists('mb_convert_encoding') ) {
JpGraphError::RaiseL(25127);
}
return mb_convert_encoding($aTxt, 'UTF-8','EUC-JP');
}
elseif( $aFF == FF_DAVID || $aFF == FF_MIRIAM || $aFF == FF_AHRON ) {
return $this->heb_iso2uni($aTxt);
}
else
return $aTxt;
}
 
// Translate iso encoding to unicode
function iso2uni ($isoline){
$uniline='';
for ($i=0; $i < strlen($isoline); $i++){
$thischar = substr($isoline,$i,1);
$charcode = ord($thischar);
$uniline .= ($charcode>175) ? "&#" . (1040+($charcode-176)). ";" : $thischar;
}
return $uniline;
}
 
// Translate greek iso encoding to unicode
function gr_iso2uni ($isoline) {
$uniline='';
for ($i=0; $i < strlen($isoline); $i++) {
$thischar=substr($isoline,$i,1);
$charcode=ord($thischar);
$uniline.=($charcode>179 && $charcode!=183 && $charcode!=187 && $charcode!=189) ? "&#" . (900+($charcode-180)). ";" : $thischar;
}
return $uniline;
}
 
// Translate greek win encoding to unicode
function gr_win2uni ($winline) {
$uniline='';
$n = strlen($winline);
for ($i=0; $i < $n; $i++) {
$thischar=substr($winline,$i,1);
$charcode=ord($thischar);
if ($charcode==161 || $charcode==162) {
$uniline.="&#" . (740+$charcode). ";";
}
else {
$uniline.=(($charcode>183 && $charcode!=187 && $charcode!=189) || $charcode==180) ? "&#" . (900+($charcode-180)). ";" : $thischar;
}
}
return $uniline;
}
 
function heb_iso2uni($isoline) {
$isoline = hebrev($isoline);
$o = '';
 
$n = strlen($isoline);
for($i=0; $i < $n; $i++) {
$c=ord( substr($isoline,$i,1) );
$o .= ($c > 223) && ($c < 251) ? '&#'.(1264+$c).';' : chr($c);
}
return utf8_encode($o);
}
}
 
//=================================================================
// CLASS TTF
// Description: Handle TTF font names and loading of font files
//=================================================================
class TTF {
var $font_files,$style_names;
 
//---------------
// CONSTRUCTOR
function TTF() {
// String names for font styles to be used in error messages
$this->style_names=array(FS_NORMAL =>'normal',
FS_BOLD =>'bold',
FS_ITALIC =>'italic',
FS_BOLDITALIC =>'bolditalic');
 
// File names for available fonts
$this->font_files=array(
FF_COURIER => array(FS_NORMAL =>'cour.ttf',
FS_BOLD =>'courbd.ttf',
FS_ITALIC =>'couri.ttf',
FS_BOLDITALIC =>'courbi.ttf' ),
FF_GEORGIA => array(FS_NORMAL =>'georgia.ttf',
FS_BOLD =>'georgiab.ttf',
FS_ITALIC =>'georgiai.ttf',
FS_BOLDITALIC =>'' ),
FF_TREBUCHE =>array(FS_NORMAL =>'trebuc.ttf',
FS_BOLD =>'trebucbd.ttf',
FS_ITALIC =>'trebucit.ttf',
FS_BOLDITALIC =>'trebucbi.ttf' ),
FF_VERDANA => array(FS_NORMAL =>'verdana.ttf',
FS_BOLD =>'verdanab.ttf',
FS_ITALIC =>'verdanai.ttf',
FS_BOLDITALIC =>'' ),
FF_TIMES => array(FS_NORMAL =>'times.ttf',
FS_BOLD =>'timesbd.ttf',
FS_ITALIC =>'timesi.ttf',
FS_BOLDITALIC =>'timesbi.ttf' ),
FF_COMIC => array(FS_NORMAL =>'comic.ttf',
FS_BOLD =>'comicbd.ttf',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_ARIAL => array(FS_NORMAL =>'arial.ttf',
FS_BOLD =>'arialbd.ttf',
FS_ITALIC =>'ariali.ttf',
FS_BOLDITALIC =>'arialbi.ttf' ) ,
FF_VERA => array(FS_NORMAL =>'Vera.ttf',
FS_BOLD =>'VeraBd.ttf',
FS_ITALIC =>'VeraIt.ttf',
FS_BOLDITALIC =>'VeraBI.ttf' ),
FF_VERAMONO => array(FS_NORMAL =>'VeraMono.ttf',
FS_BOLD =>'VeraMoBd.ttf',
FS_ITALIC =>'VeraMoIt.ttf',
FS_BOLDITALIC =>'VeraMoBI.ttf' ),
FF_VERASERIF=> array(FS_NORMAL =>'VeraSe.ttf',
FS_BOLD =>'VeraSeBd.ttf',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ) ,
 
/* Chinese fonts */
FF_SIMSUN => array(FS_NORMAL =>'simsun.ttc',
FS_BOLD =>'simhei.ttf',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_CHINESE => array(FS_NORMAL =>CHINESE_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
 
/* Japanese fonts */
FF_MINCHO => array(FS_NORMAL =>MINCHO_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_PMINCHO => array(FS_NORMAL =>PMINCHO_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_GOTHIC => array(FS_NORMAL =>GOTHIC_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_PGOTHIC => array(FS_NORMAL =>PGOTHIC_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_MINCHO => array(FS_NORMAL =>PMINCHO_TTF_FONT,
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
 
/* Hebrew fonts */
FF_DAVID => array(FS_NORMAL =>'DAVIDNEW.TTF',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
 
FF_MIRIAM => array(FS_NORMAL =>'MRIAMY.TTF',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
 
FF_AHRON => array(FS_NORMAL =>'ahronbd.ttf',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
 
/* Dejavu fonts */
FF_DV_SANSSERIF => array(FS_NORMAL =>'DejaVuSans.ttf',
FS_BOLD =>'DejaVuSans-Bold.ttf',
FS_ITALIC =>'DejaVuSans-Oblique.ttf',
FS_BOLDITALIC =>'DejaVuSans-BoldOblique.ttf' ),
 
FF_DV_SANSSERIFMONO => array(FS_NORMAL =>'DejaVuSansMono.ttf',
FS_BOLD =>'DejaVuSansMono-Bold.ttf',
FS_ITALIC =>'DejaVuSansMono-Oblique.ttf',
FS_BOLDITALIC =>'DejaVuSansMono-BoldOblique.ttf' ),
 
FF_DV_SANSSERIFCOND => array(FS_NORMAL =>'DejaVuSansCondensed.ttf',
FS_BOLD =>'DejaVuSansCondensed-Bold.ttf',
FS_ITALIC =>'DejaVuSansCondensed-Oblique.ttf',
FS_BOLDITALIC =>'DejaVuSansCondensed-BoldOblique.ttf' ),
 
FF_DV_SERIF => array(FS_NORMAL =>'DejaVuSerif.ttf',
FS_BOLD =>'DejaVuSerif-Bold.ttf',
FS_ITALIC =>'DejaVuSerif-Italic.ttf',
FS_BOLDITALIC =>'DejaVuSerif-BoldItalic.ttf' ),
 
FF_DV_SERIFCOND => array(FS_NORMAL =>'DejaVuSerifCondensed.ttf',
FS_BOLD =>'DejaVuSerifCondensed-Bold.ttf',
FS_ITALIC =>'DejaVuSerifCondensed-Italic.ttf',
FS_BOLDITALIC =>'DejaVuSerifCondensed-BoldItalic.ttf' ),
 
/* Misc fonts */
FF_DIGITAL => array(FS_NORMAL =>'DIGIRU__.TTF',
FS_BOLD =>'Digirtu_.ttf',
FS_ITALIC =>'Digir___.ttf',
FS_BOLDITALIC =>'DIGIRT__.TTF' ),
FF_SPEEDO => array(FS_NORMAL =>'Speedo.ttf',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_COMPUTER => array(FS_NORMAL =>'COMPUTER.TTF',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
FF_CALCULATOR =>array(FS_NORMAL =>'Triad_xs.ttf',
FS_BOLD =>'',
FS_ITALIC =>'',
FS_BOLDITALIC =>'' ),
);
}
 
//---------------
// PUBLIC METHODS
// Create the TTF file from the font specification
function File($family,$style=FS_NORMAL) {
if( $family == FF_HANDWRT || $family==FF_BOOK ) {
JpGraphError::RaiseL(25045);//('Font families FF_HANDWRT and FF_BOOK are no longer available due to copyright problem with these fonts. Fonts can no longer be distributed with JpGraph. Please download fonts from http://corefonts.sourceforge.net/');
}
 
$fam = @$this->font_files[$family];
if( !$fam ) {
JpGraphError::RaiseL(25046,$family);//("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/");
}
$f = @$fam[$style];
 
if( $f==='' )
JpGraphError::RaiseL(25047,$this->style_names[$style],$this->font_files[$family][FS_NORMAL]);//('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.');
if( !$f ) {
JpGraphError::RaiseL(25048,$fam);//("Unknown font style specification [$fam].");
}
 
if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) {
$f = MBTTF_DIR.$f;
} else {
$f = TTF_DIR.$f;
}
 
if( file_exists($f) === false || is_readable($f) === false ) {
JpGraphError::RaiseL(25049,$f);//("Font file \"$f\" is not readable or does not exist.");
}
return $f;
}
} // Class
 
?>