Index: include/docweb_dao_metainfo.class.php =================================================================== RCS file: /repository/docweb/include/docweb_dao_metainfo.class.php,v retrieving revision 1.2 diff -u -r1.2 docweb_dao_metainfo.class.php --- include/docweb_dao_metainfo.class.php 7 Feb 2005 05:04:06 -0000 1.2 +++ include/docweb_dao_metainfo.class.php 4 Dec 2006 23:06:54 -0000 @@ -86,7 +86,7 @@ /** * Determines if the passed function name is an alias * - * @param string $func + * @param string $func * @return bool */ function isAlias($func) @@ -201,4 +201,4 @@ } } -?> \ No newline at end of file +?> Index: include/lib_auth.inc.php =================================================================== RCS file: /repository/docweb/include/lib_auth.inc.php,v retrieving revision 1.14 diff -u -r1.14 lib_auth.inc.php --- include/lib_auth.inc.php 3 Oct 2006 23:22:28 -0000 1.14 +++ include/lib_auth.inc.php 4 Dec 2006 23:06:54 -0000 @@ -23,19 +23,19 @@ require_once 'cvs-auth.inc'; if (!$idx = sqlite_open(SQLITE_DIR . 'users.sqlite')) { - die ('auth DB not available'); + die ('auth DB not available'); } //list of docweb admins that have 'special' rights $admins = array( - 'didou', - 'goba', - 'jacques', - 'nlopess', - 'philip', - 'sean', - 'vincent', - 'mazzanet', + 'didou', + 'goba', + 'jacques', + 'nlopess', + 'philip', + 'sean', + 'vincent', + 'mazzanet', 'colder', ); @@ -43,7 +43,7 @@ // make the username & password global if (isset($_COOKIE['MAGIC_COOKIE'])) { - list($user, $password) = explode(':', base64_decode(@$_COOKIE['MAGIC_COOKIE']), 2); + list($user, $password) = explode(':', base64_decode(@$_COOKIE['MAGIC_COOKIE']), 2); } /** @@ -51,32 +51,32 @@ */ function auth() { - global $user, $password; + global $user, $password; $return = $_SERVER['REQUEST_URI']; - if (isset($_COOKIE['MAGIC_COOKIE'])) { + if (isset($_COOKIE['MAGIC_COOKIE'])) { - if (!verify_password($user, $password)) { - header ('Location: http://doc.php.net/login.php?return='.$return); - exit; - } - } elseif (isset($_POST['username']) && isset($_POST['passwd'])) { - if (!verify_password($_POST['username'], $_POST['passwd'])) { - header ('Location: http://doc.php.net/login.php?return='.$return); - exit; - } - - setcookie( - 'MAGIC_COOKIE', - base64_encode("{$_POST['username']}:{$_POST['passwd']}"), - time()+3600*24*12, - '/', - '.php.net' - ); - } else { - header ('Location: http://doc.php.net/login.php?return='.$return); - exit; - } + if (!verify_password($user, $password)) { + header ('Location: http://doc.php.net/login.php?return='.$return); + exit; + } + } elseif (isset($_POST['username']) && isset($_POST['passwd'])) { + if (!verify_password($_POST['username'], $_POST['passwd'])) { + header ('Location: http://doc.php.net/login.php?return='.$return); + exit; + } + + setcookie( + 'MAGIC_COOKIE', + base64_encode("{$_POST['username']}:{$_POST['passwd']}"), + time()+3600*24*12, + '/', + '.php.net' + ); + } else { + header ('Location: http://doc.php.net/login.php?return='.$return); + exit; + } } @@ -85,7 +85,7 @@ */ function is_admin() { - return in_array($GLOBALS['user'], $GLOBALS['admins']); + return in_array($GLOBALS['user'], $GLOBALS['admins']); } @@ -94,15 +94,15 @@ */ function user_info($u = false) { - global $idx, $user; + global $idx, $user; - $u = $u ? $u : $user; - $result = @sqlite_unbuffered_query($idx, "SELECT * FROM users WHERE username='" . sqlite_escape_string($u) . "'"); - if (!$result) { - return false; - } + $u = $u ? $u : $user; + $result = @sqlite_unbuffered_query($idx, "SELECT * FROM users WHERE username='" . sqlite_escape_string($u) . "'"); + if (!$result) { + return false; + } - return sqlite_fetch_array($result, SQLITE_ASSOC); + return sqlite_fetch_array($result, SQLITE_ASSOC); } @@ -111,14 +111,14 @@ */ function user_name($user = false) { - $user = $user ? $user : $GLOBALS['user']; + $user = $user ? $user : $GLOBALS['user']; - // first check if the name is in the DB - if ($info = user_info($user)) - return $info['name']; + // first check if the name is in the DB + if ($info = user_info($user)) + return $info['name']; - //no, it isn't. fetch it from the master server - return master_user_name($user); + //no, it isn't. fetch it from the master server + return master_user_name($user); } @@ -127,28 +127,28 @@ */ function master_user_name($nick) { - $magic_cookie = (!empty($_COOKIE['MAGIC_COOKIE'])) ? - $_COOKIE['MAGIC_COOKIE'] : + $magic_cookie = (!empty($_COOKIE['MAGIC_COOKIE'])) ? + $_COOKIE['MAGIC_COOKIE'] : '' ; // need a generic key here!! - if (!$fp = @fsockopen('master.php.net', 80)) - return $nick; + if (!$fp = @fsockopen('master.php.net', 80)) + return $nick; - fputs($fp, "GET /manage/users.php?username=$nick HTTP/1.0\r\n". - "Host: master.php.net\r\n". - "Cookie: MAGIC_COOKIE=$magic_cookie\r\n". - "\r\n"); - - $txt = @fread($fp, 50000); - fclose($fp); - - // if we found a name, cache it in the DB - if (preg_match('@]+>Name:\s+]+value="([^"]+)"@', $txt, $match)) { - sqlite_query($GLOBALS['idx'], "INSERT INTO users (username, name) VALUES ('$nick', '$match[1]')"); //the server has no sqlite_exec support yet (still php4) - return $match[1]; - } + fputs($fp, "GET /manage/users.php?username=$nick HTTP/1.0\r\n". + "Host: master.php.net\r\n". + "Cookie: MAGIC_COOKIE=$magic_cookie\r\n". + "\r\n"); + + $txt = @fread($fp, 50000); + fclose($fp); + + // if we found a name, cache it in the DB + if (preg_match('@]+>Name:\s+]+value="([^"]+)"@', $txt, $match)) { + sqlite_query($GLOBALS['idx'], "INSERT INTO users (username, name) VALUES ('$nick', '$match[1]')"); //the server has no sqlite_exec support yet (still php4) + return $match[1]; + } - return $nick; + return $nick; } ?> Index: include/lib_proj_lang.inc.php =================================================================== RCS file: /repository/docweb/include/lib_proj_lang.inc.php,v retrieving revision 1.6 diff -u -r1.6 lib_proj_lang.inc.php --- include/lib_proj_lang.inc.php 14 Sep 2005 08:00:35 -0000 1.6 +++ include/lib_proj_lang.inc.php 4 Dec 2006 23:06:54 -0000 @@ -27,13 +27,13 @@ // Map of supported documentation types to CVS module names $PROJECTS = array( // project => (Name, local folder, cvs module) - 'www' => array('Documentation', '', ''), - 'php' => array('PHP Documentation', 'phpdoc-all', 'phpdoc/en'), - 'smarty' => array('Smarty', 'smarty/docs', 'smarty/docs/en'), - 'pear' => array('PEAR Documentation', 'peardoc', 'peardoc/en'), - 'gtk' => array('PHP-GTK Documentation', 'php-gtk-doc', 'php-gtk-doc/manual/en'), - 'livedocs' => array('Livedocs', '', ''), - 'pecl' => array('PECL Documentation', '', ''), + 'www' => array('Documentation', '', ''), + 'php' => array('PHP Documentation', 'phpdoc-all', 'phpdoc/en'), + 'smarty' => array('Smarty', 'smarty/docs', 'smarty/docs/en'), + 'pear' => array('PEAR Documentation', 'peardoc', 'peardoc/en'), + 'gtk' => array('PHP-GTK Documentation', 'php-gtk-doc', 'php-gtk-doc/manual/en'), + 'livedocs' => array('Livedocs', '', ''), + 'pecl' => array('PECL Documentation', '', ''), ); // Supported languages Index: include/lib_revcheck.inc.php =================================================================== RCS file: /repository/docweb/include/lib_revcheck.inc.php,v retrieving revision 1.14 diff -u -r1.14 lib_revcheck.inc.php --- include/lib_revcheck.inc.php 5 Feb 2006 22:19:53 -0000 1.14 +++ include/lib_revcheck.inc.php 4 Dec 2006 23:06:55 -0000 @@ -409,17 +409,17 @@ AND ( b.revision - a.revision >= ' . ALERT_REV . ' - OR - ( - b.revision != a.revision - AND - ( + OR + ( + b.revision != a.revision + AND + ( b.size - a.size >= ' . (1024 * ALERT_SIZE) . ' OR php("intval",(b.mdate - a.mdate) / 86400) >= ' . ALERT_DATE . ' - ) + ) ) - ) + ) AND a.size is not NULL GROUP BY @@ -651,7 +651,7 @@ WHERE a.lang="' . $lang . '" AND - b.lang="en" + b.lang="en" AND a.revision is NULL AND Index: include/jpgraph/jpgraph_bar.php =================================================================== RCS file: /repository/docweb/include/jpgraph/jpgraph_bar.php,v retrieving revision 1.1 diff -u -r1.1 jpgraph_bar.php --- include/jpgraph/jpgraph_bar.php 4 Aug 2004 17:14:55 -0000 1.1 +++ include/jpgraph/jpgraph_bar.php 4 Dec 2006 23:06:55 -0000 @@ -1,12 +1,12 @@ Plot($datay,$datax); - ++$this->numpoints; + $this->Plot($datay,$datax); + ++$this->numpoints; } //--------------- -// PUBLIC METHODS - +// 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; + $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; + //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; + $this->ybase=$aYStartValue; } - + function Legend(&$graph) { - if( $this->grad && $this->legend!="" && !$this->fill ) { - $color=array($this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); - $graph->legend->Add($this->legend,$color,"",0, - $this->legendcsimtarget,$this->legendcsimalt); - } - elseif( $this->fill_color && $this->legend!="" ) { - if( is_array($this->fill_color) ) - $graph->legend->Add($this->legend,$this->fill_color[0],"",0, - $this->legendcsimtarget,$this->legendcsimalt); - else - $graph->legend->Add($this->legend,$this->fill_color,"",0, - $this->legendcsimtarget,$this->legendcsimalt); - } + if( $this->grad && $this->legend!="" && !$this->fill ) { + $color=array($this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); + $graph->legend->Add($this->legend,$color,"",0, + $this->legendcsimtarget,$this->legendcsimalt); + } + elseif( $this->fill_color && $this->legend!="" ) { + if( is_array($this->fill_color) ) + $graph->legend->Add($this->legend,$this->fill_color[0],"",0, + $this->legendcsimtarget,$this->legendcsimalt); + else + $graph->legend->Add($this->legend,$this->fill_color,"",0, + $this->legendcsimtarget,$this->legendcsimalt); + } } // Gets called before any axis are stroked function PreStrokeAdjust(&$graph) { - parent::PreStrokeAdjust($graph); + 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->align == "center" ) - $graph->SetTextScaleOff(0.5-$this->width/2); - elseif( $this->align == "right" ) - $graph->SetTextScaleOff(1-$this->width); - - } - else { - // 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 ) { + // 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->align == "center" ) + $graph->SetTextScaleOff(0.5-$this->width/2); + elseif( $this->align == "right" ) + $graph->SetTextScaleOff(1-$this->width); + + } + else { + // 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])); - } - } + // 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; + $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; - } - + $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($aFractionWidth) { - $this->width=$aFractionWidth; + $this->width=$aFractionWidth; } - + // Specify width in absolute pixels. If specified this // overrides SetWidth() function SetAbsWidth($aWidth) { - $this->abswidth=$aWidth; + $this->abswidth=$aWidth; } - + function SetAlign($aAlign) { - $this->align=$aAlign; + $this->align=$aAlign; } - + function SetNoFill() { - $this->grad = false; - $this->fill_color=false; - $this->fill=false; + $this->grad = false; + $this->fill_color=false; + $this->fill=false; } - + function SetFillColor($aColor) { - $this->fill = true ; - $this->fill_color=$aColor; + $this->fill = true ; + $this->fill_color=$aColor; } - + function SetFillGradient($from_color,$to_color,$style) { - $this->grad=true; - $this->grad_fromcolor=$from_color; - $this->grad_tocolor=$to_color; - $this->grad_style=$style; + $this->grad=true; + $this->grad_fromcolor=$from_color; + $this->grad_tocolor=$to_color; + $this->grad_style=$style; } - + function SetValuePos($aPos) { - $this->valuepos = $aPos; + $this->valuepos = $aPos; } function SetPattern($aPattern, $aColor='black'){ - $this->iPatternColor = $aColor; - switch( $aPattern ) { - case PATTERN_DIAG1: - $this->iPattern = 1; - $this->iPatternDensity = 90; - break; - case PATTERN_DIAG2: - $this->iPattern = 1; - $this->iPatternDensity = 75; - break; - case PATTERN_DIAG3: - $this->iPattern = 2; - $this->iPatternDensity = 90; - break; - case PATTERN_DIAG4: - $this->iPattern = 2; - $this->iPatternDensity = 75; - break; - case PATTERN_CROSS1: - $this->iPattern = 8; - $this->iPatternDensity = 90; - break; - case PATTERN_CROSS2: - $this->iPattern = 8; - $this->iPatternDensity = 78; - break; - case PATTERN_CROSS3: - $this->iPattern = 8; - $this->iPatternDensity = 65; - break; - case PATTERN_CROSS4: - $this->iPattern = 7; - $this->iPatternDensity = 90; - break; - case PATTERN_STRIPE1: - $this->iPattern = 5; - $this->iPatternDensity = 90; - break; - case PATTERN_STRIPE2: - $this->iPattern = 5; - $this->iPatternDensity = 75; - break; - default: - JpGraphError::Raise('Unknown pattern specified in call to BarPlot::SetPattern()'); + $this->iPatternColor = $aColor; + switch( $aPattern ) { + case PATTERN_DIAG1: + $this->iPattern = 1; + $this->iPatternDensity = 90; + break; + case PATTERN_DIAG2: + $this->iPattern = 1; + $this->iPatternDensity = 75; + break; + case PATTERN_DIAG3: + $this->iPattern = 2; + $this->iPatternDensity = 90; + break; + case PATTERN_DIAG4: + $this->iPattern = 2; + $this->iPatternDensity = 75; + break; + case PATTERN_CROSS1: + $this->iPattern = 8; + $this->iPatternDensity = 90; + break; + case PATTERN_CROSS2: + $this->iPattern = 8; + $this->iPatternDensity = 78; + break; + case PATTERN_CROSS3: + $this->iPattern = 8; + $this->iPatternDensity = 65; + break; + case PATTERN_CROSS4: + $this->iPattern = 7; + $this->iPatternDensity = 90; + break; + case PATTERN_STRIPE1: + $this->iPattern = 5; + $this->iPatternDensity = 90; + break; + case PATTERN_STRIPE2: + $this->iPattern = 5; + $this->iPatternDensity = 75; + break; + default: + JpGraphError::Raise('Unknown pattern specified in call to BarPlot::SetPattern()'); - } + } } function Stroke(&$img,&$xscale,&$yscale) { - - $numpoints = count($this->coords[0]); - if( isset($this->coords[1]) ) { - if( count($this->coords[1])!=$numpoints ) - die("JpGraph Error: 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); - - for($i=0; $i<$numbars; $i++) { - - // If value is NULL, or 0 then don't draw a bar at all - if ($this->coords[0][$i] === null || - $this->coords[0][$i] === '' || - $this->coords[0][$i] === 0 ) continue; - - if( $exist_x ) $x=$this->coords[1][$i]; - else $x=$i; - - $x=$xscale->Translate($x); - - if( !$xscale->textscale ) { - if($this->align=="center") - $x -= $abswidth/2; - elseif($this->align=="right") - $x -= $abswidth; - } - - - // Stroke fill color and fill gradient - $pts=array( - $x,$zp, - $x,$yscale->Translate($this->coords[0][$i]), - $x+$abswidth,$yscale->Translate($this->coords[0][$i]), - $x+$abswidth,$zp); - if( $this->grad ) { - $grad = new Gradient($img); - $grad->FilledRectangle($pts[2],$pts[3], - $pts[6],$pts[7], - $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); - } - elseif( !empty($this->fill_color) ) { - if(is_array($this->fill_color)) { - $img->PushColor($this->fill_color[$i % count($this->fill_color)]); - } else { - $img->PushColor($this->fill_color); - } - $img->FilledPolygon($pts); - $img->PopColor(); - } + + $numpoints = count($this->coords[0]); + if( isset($this->coords[1]) ) { + if( count($this->coords[1])!=$numpoints ) + die("JpGraph Error: 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); + + for($i=0; $i<$numbars; $i++) { + + // If value is NULL, or 0 then don't draw a bar at all + if ($this->coords[0][$i] === null || + $this->coords[0][$i] === '' || + $this->coords[0][$i] === 0 ) continue; + + if( $exist_x ) $x=$this->coords[1][$i]; + else $x=$i; + + $x=$xscale->Translate($x); + + if( !$xscale->textscale ) { + if($this->align=="center") + $x -= $abswidth/2; + elseif($this->align=="right") + $x -= $abswidth; + } + + + // Stroke fill color and fill gradient + $pts=array( + $x,$zp, + $x,$yscale->Translate($this->coords[0][$i]), + $x+$abswidth,$yscale->Translate($this->coords[0][$i]), + $x+$abswidth,$zp); + if( $this->grad ) { + $grad = new Gradient($img); + $grad->FilledRectangle($pts[2],$pts[3], + $pts[6],$pts[7], + $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); + } + elseif( !empty($this->fill_color) ) { + if(is_array($this->fill_color)) { + $img->PushColor($this->fill_color[$i % count($this->fill_color)]); + } else { + $img->PushColor($this->fill_color); + } + $img->FilledPolygon($pts); + $img->PopColor(); + } - - // Remember value of this bar - $val=$this->coords[0][$i]; - - if( !empty($val) && !is_numeric($val) ) { - JpGraphError::Raise('All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); - } - - // Determine the shadow - if( $this->bar_shadow && $val != 0) { - - $ssh = $this->bar_shadow_hsize; - $ssv = $this->bar_shadow_vsize; - // Create points to create a "upper-right" shadow - if( $val > 0 ) { - $sp[0]=$pts[6]; $sp[1]=$pts[7]; - $sp[2]=$pts[4]; $sp[3]=$pts[5]; - $sp[4]=$pts[2]; $sp[5]=$pts[3]; - $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; - $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; - $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; - } - elseif( $val < 0 ) { - $sp[0]=$pts[4]; $sp[1]=$pts[5]; - $sp[2]=$pts[6]; $sp[3]=$pts[7]; - $sp[4]=$pts[0]; $sp[5]=$pts[1]; - $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; - $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; - $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; - } - if( is_array($this->bar_shadow_color) ) { - $numcolors = count($this->bar_shadow_color); - if( $numcolors == 0 ) { - JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.'); - } - $img->PushColor($this->bar_shadow_color[$i % $numcolors]); - } - else { - $img->PushColor($this->bar_shadow_color); - } - $img->FilledPolygon($sp); - $img->PopColor(); - } - - // Stroke the pattern - if( $this->iPattern > -1 ) { - $f = new RectPatternFactory(); - $prect = $f->Create($this->iPattern,$this->iPatternColor,1); - $prect->SetDensity($this->iPatternDensity); - $prect->SetPos(new Rectangle($pts[2],$pts[3],$pts[4]-$pts[0]+1,$pts[1]-$pts[3]+1)); - $prect->Stroke($img); - } - - // Stroke the outline of the bar - if( is_array($this->color) ) - $img->SetColor($this->color[$i % count($this->color)]); - else - $img->SetColor($this->color); - - $pts[] = $pts[0]; - $pts[] = $pts[1]; - - if( $this->weight > 0 ) { - $img->SetLineWeight($this->weight); - $img->Polygon($pts); - } - - // Determine how to best position the values of the individual bars - $x=$pts[2]+($pts[4]-$pts[2])/2; - if( $this->valuepos=='top' ) { - $y=$pts[3]; - if( $img->a === 90 ) { - if( $val < 0 ) - $this->value->SetAlign('right','center'); - else - $this->value->SetAlign('left','center'); - - } - $this->value->Stroke($img,$val,$x,$y); - } - elseif( $this->valuepos=='max' ) { - $y=$pts[3]; - if( $img->a === 90 ) { - if( $val < 0 ) - $this->value->SetAlign('left','center'); - else - $this->value->SetAlign('right','center'); - } - else { - $this->value->SetAlign('center','top'); - } - $this->value->SetMargin(-3); - $this->value->Stroke($img,$val,$x,$y); - } - elseif( $this->valuepos=='center' ) { - $y = ($pts[3] + $pts[1])/2; - $this->value->SetAlign('center','center'); - $this->value->SetMargin(0); - $this->value->Stroke($img,$val,$x,$y); - } - elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { - $y=$pts[1]; - if( $img->a === 90 ) { - if( $val < 0 ) - $this->value->SetAlign('right','center'); - else - $this->value->SetAlign('left','center'); - } - $this->value->SetMargin(3); - $this->value->Stroke($img,$val,$x,$y); - } - else { - JpGraphError::Raise('Unknown position for values on bars :'.$this->valuepos); - die(); - } - // Create the client side image map - $rpts = $img->ArrRotate($pts); - $csimcoord=round($rpts[0]).", ".round($rpts[1]); - for( $j=1; $j < 4; ++$j){ - $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); - } - if( !empty($this->csimtargets[$i]) ) { - $this->csimareas .= 'csimareas .= " href=\"".$this->csimtargets[$i]."\""; - if( !empty($this->csimalts[$i]) ) { - $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); - $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; - } - $this->csimareas .= ">\n"; - } - } - return true; + + // Remember value of this bar + $val=$this->coords[0][$i]; + + if( !empty($val) && !is_numeric($val) ) { + JpGraphError::Raise('All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); + } + + // Determine the shadow + if( $this->bar_shadow && $val != 0) { + + $ssh = $this->bar_shadow_hsize; + $ssv = $this->bar_shadow_vsize; + // Create points to create a "upper-right" shadow + if( $val > 0 ) { + $sp[0]=$pts[6]; $sp[1]=$pts[7]; + $sp[2]=$pts[4]; $sp[3]=$pts[5]; + $sp[4]=$pts[2]; $sp[5]=$pts[3]; + $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; + $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; + $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; + } + elseif( $val < 0 ) { + $sp[0]=$pts[4]; $sp[1]=$pts[5]; + $sp[2]=$pts[6]; $sp[3]=$pts[7]; + $sp[4]=$pts[0]; $sp[5]=$pts[1]; + $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; + $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; + $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; + } + if( is_array($this->bar_shadow_color) ) { + $numcolors = count($this->bar_shadow_color); + if( $numcolors == 0 ) { + JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.'); + } + $img->PushColor($this->bar_shadow_color[$i % $numcolors]); + } + else { + $img->PushColor($this->bar_shadow_color); + } + $img->FilledPolygon($sp); + $img->PopColor(); + } + + // Stroke the pattern + if( $this->iPattern > -1 ) { + $f = new RectPatternFactory(); + $prect = $f->Create($this->iPattern,$this->iPatternColor,1); + $prect->SetDensity($this->iPatternDensity); + $prect->SetPos(new Rectangle($pts[2],$pts[3],$pts[4]-$pts[0]+1,$pts[1]-$pts[3]+1)); + $prect->Stroke($img); + } + + // Stroke the outline of the bar + if( is_array($this->color) ) + $img->SetColor($this->color[$i % count($this->color)]); + else + $img->SetColor($this->color); + + $pts[] = $pts[0]; + $pts[] = $pts[1]; + + if( $this->weight > 0 ) { + $img->SetLineWeight($this->weight); + $img->Polygon($pts); + } + + // Determine how to best position the values of the individual bars + $x=$pts[2]+($pts[4]-$pts[2])/2; + if( $this->valuepos=='top' ) { + $y=$pts[3]; + if( $img->a === 90 ) { + if( $val < 0 ) + $this->value->SetAlign('right','center'); + else + $this->value->SetAlign('left','center'); + + } + $this->value->Stroke($img,$val,$x,$y); + } + elseif( $this->valuepos=='max' ) { + $y=$pts[3]; + if( $img->a === 90 ) { + if( $val < 0 ) + $this->value->SetAlign('left','center'); + else + $this->value->SetAlign('right','center'); + } + else { + $this->value->SetAlign('center','top'); + } + $this->value->SetMargin(-3); + $this->value->Stroke($img,$val,$x,$y); + } + elseif( $this->valuepos=='center' ) { + $y = ($pts[3] + $pts[1])/2; + $this->value->SetAlign('center','center'); + $this->value->SetMargin(0); + $this->value->Stroke($img,$val,$x,$y); + } + elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { + $y=$pts[1]; + if( $img->a === 90 ) { + if( $val < 0 ) + $this->value->SetAlign('right','center'); + else + $this->value->SetAlign('left','center'); + } + $this->value->SetMargin(3); + $this->value->Stroke($img,$val,$x,$y); + } + else { + JpGraphError::Raise('Unknown position for values on bars :'.$this->valuepos); + die(); + } + // Create the client side image map + $rpts = $img->ArrRotate($pts); + $csimcoord=round($rpts[0]).", ".round($rpts[1]); + for( $j=1; $j < 4; ++$j){ + $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); + } + if( !empty($this->csimtargets[$i]) ) { + $this->csimareas .= 'csimareas .= " href=\"".$this->csimtargets[$i]."\""; + if( !empty($this->csimalts[$i]) ) { + $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); + $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; + } + $this->csimareas .= ">\n"; + } + } + return true; } } // Class @@ -447,78 +447,78 @@ //--------------- // CONSTRUCTOR function GroupBarPlot($plots) { - $this->plots = $plots; - $this->nbrplots = count($plots); - if( $this->nbrplots < 1 ) { - JpGraphError::Raise('You must have at least one barplot in the array to be able to create a Grouped Bar Plot.'); - } - $this->numpoints = $plots[0]->numpoints; + $this->plots = $plots; + $this->nbrplots = count($plots); + if( $this->nbrplots < 1 ) { + JpGraphError::Raise('You must have at least one barplot in the array to be able to create a Grouped Bar Plot.'); + } + $this->numpoints = $plots[0]->numpoints; } //--------------- -// PUBLIC METHODS +// PUBLIC METHODS function Legend(&$graph) { - $n = count($this->plots); - for($i=0; $i < $n; ++$i) { - $c = get_class($this->plots[$i]); - $sc = is_subclass_of($this->plots[$i],'barplot'); - if( $c !== 'barplot' && !$sc ) { - JpGraphError::Raise('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects.'); - } - $this->plots[$i]->DoLegend($graph); - } + $n = count($this->plots); + for($i=0; $i < $n; ++$i) { + $c = get_class($this->plots[$i]); + $sc = is_subclass_of($this->plots[$i],'barplot'); + if( $c !== 'barplot' && !$sc ) { + JpGraphError::Raise('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects.'); + } + $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); + 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); + 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; + $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->ticks->major_step* */ - $xscale->scale_factor*$subwidth); - $this->plots[$i]->Stroke($img,$xscale,$yscale); - } - $xscale->off=$tmp; + $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->ticks->major_step* */ + $xscale->scale_factor*$subwidth); + $this->plots[$i]->Stroke($img,$xscale,$yscale); + } + $xscale->off=$tmp; } } // Class @@ -531,266 +531,266 @@ //--------------- // CONSTRUCTOR function AccBarPlot($plots) { - $this->plots = $plots; - $this->nbrplots = count($plots); - $this->numpoints = $plots[0]->numpoints; - $this->value = new DisplayValue(); + $this->plots = $plots; + $this->nbrplots = count($plots); + $this->numpoints = $plots[0]->numpoints; + $this->value = new DisplayValue(); } //--------------- -// PUBLIC METHODS +// PUBLIC METHODS function Legend(&$graph) { - $n = count($this->plots); - for( $i=$n-1; $i >= 0; --$i ) { - $c = get_class($this->plots[$i]); - if( $c !== 'barplot' ) { - JpGraphError::Raise('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.'); - } - $this->plots[$i]->DoLegend($graph); - } + $n = count($this->plots); + for( $i=$n-1; $i >= 0; --$i ) { + $c = get_class($this->plots[$i]); + if( $c !== 'barplot' ) { + JpGraphError::Raise('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.'); + } + $this->plots[$i]->DoLegend($graph); + } } function Max() { - list($xmax) = $this->plots[0]->Max(); - $nmax=0; - for($i=0; $iplots); ++$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( $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]; - } - $ymax[$i] = $y; - } - $ymax = max($ymax); - - // Bar always start at baseline - if( $ymax <= $this->ybase ) - $ymax = $this->ybase; - return array($xmax,$ymax); + list($xmax) = $this->plots[0]->Max(); + $nmax=0; + for($i=0; $iplots); ++$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( $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]; + } + $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; $iplots); ++$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=$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)); - // Bar always start at baseline - if( $ymin >= $this->ybase ) - $ymin = $this->ybase; - return array($xmin,$ymin); + $nmax=0; + list($xmin,$ysetmin) = $this->plots[0]->Min(); + for($i=0; $iplots); ++$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=$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)); + // Bar always start at baseline + if( $ymin >= $this->ybase ) + $ymin = $this->ybase; + return array($xmin,$ymin); } // Stroke acc bar plot function Stroke(&$img,&$xscale,&$yscale) { - $pattern=NULL; - $img->SetLineWeight($this->weight); - for($i=0; $i < $this->numpoints-1; $i++) { - $accy = 0; - $accy_neg = 0; - for($j=0; $j < $this->nbrplots; ++$j ) { - - $img->SetColor($this->plots[$j]->color); - - if ( $this->plots[$j]->coords[0][$i] >= 0) { - $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); - $accyt=$yscale->Translate($accy); - $accy+=$this->plots[$j]->coords[0][$i]; - } - else { - //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { - $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); - $accyt=$yscale->Translate($accy_neg); - $accy_neg+=$this->plots[$j]->coords[0][$i]; - } - - $xt=$xscale->Translate($i); - - if( $this->abswidth > -1 ) - $abswidth=$this->abswidth; - else - $abswidth=round($this->width*$xscale->scale_factor,0); - - $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); - - if( $this->bar_shadow ) { - $ssh = $this->bar_shadow_hsize; - $ssv = $this->bar_shadow_vsize; - - // We must also differ if we are a positive or negative bar. - if( $j === 0 ) { - // This gets extra complicated since we have to - // see all plots to see if we are negative. It could - // for example be that all plots are 0 until the very - // last one. We therefore need to save the initial setup - // for both the negative and positive case - - // In case the final bar is positive - $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; - $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; - - // In case the final bar is negative - $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; - $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; - $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; - $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; - } - - if( $j === $this->nbrplots-1 ) { - // If this is the last plot of the bar and - // the total value is larger than 0 then we - // add the shadow. - if( is_array($this->bar_shadow_color) ) { - $numcolors = count($this->bar_shadow_color); - if( $numcolors == 0 ) { - JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.'); - } - $img->PushColor($this->bar_shadow_color[$i % $numcolors]); - } - else { - $img->PushColor($this->bar_shadow_color); - } - - if( $accy > 0 ) { - $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; - $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; - $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; - $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; - $img->FilledPolygon($sp,4); - } - elseif( $accy_neg < 0 ) { - $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; - $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; - $img->FilledPolygon($nsp,4); - } - $img->PopColor(); - } - } - - - // If value is NULL or 0, then don't draw a bar at all - if ($this->plots[$j]->coords[0][$i] == 0 ) continue; - - if( $this->plots[$j]->grad ) { - $grad = new Gradient($img); - $grad->FilledRectangle( - $pts[2],$pts[3], - $pts[6],$pts[7], - $this->plots[$j]->grad_fromcolor, - $this->plots[$j]->grad_tocolor, - $this->plots[$j]->grad_style); - } else { - if (is_array($this->plots[$j]->fill_color) ) { - $numcolors = count($this->plots[$j]->fill_color); - $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); - } - else { - $img->SetColor($this->plots[$j]->fill_color); - } - $img->FilledPolygon($pts); - $img->SetColor($this->plots[$j]->color); - } - - // Stroke the pattern - if( $this->plots[$j]->iPattern > -1 ) { - if( $pattern===NULL ) - $pattern = new RectPatternFactory(); - - $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); - $prect->SetDensity($this->plots[$j]->iPatternDensity); - $prect->SetPos(new Rectangle($pts[2],$pts[3],$pts[4]-$pts[0]+1,$pts[1]-$pts[3]+1)); - $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.= 'csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\""; - if( !empty($this->plots[$j]->csimalts[$i]) ) { - $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); - $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; - } - $this->csimareas .= ">\n"; - } - } - - $pts[] = $pts[0]; - $pts[] = $pts[1]; - $img->Polygon($pts); - } - - // Draw labels for each acc.bar - - $x=$pts[2]+($pts[4]-$pts[2])/2; - $y=$yscale->Translate($accy); - if($this->bar_shadow) $x += $ssh; - $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); - $y = $accyt-($accyt-$yt)/2; - $accy+=$this->plots[$j]->coords[0][$i]; - } else { - $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); - $accyt=$yscale->Translate($accy_neg); - //$y=0; - $accy_neg+=$this->plots[$j]->coords[0][$i]; - $y = $accyt-($accyt-$yt)/2; // TODO : Check this fix - } - $this->plots[$j]->value->SetAlign("center","center"); - $this->plots[$j]->value->SetMargin(0); - $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); - } + $pattern=NULL; + $img->SetLineWeight($this->weight); + for($i=0; $i < $this->numpoints-1; $i++) { + $accy = 0; + $accy_neg = 0; + for($j=0; $j < $this->nbrplots; ++$j ) { + + $img->SetColor($this->plots[$j]->color); + + if ( $this->plots[$j]->coords[0][$i] >= 0) { + $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); + $accyt=$yscale->Translate($accy); + $accy+=$this->plots[$j]->coords[0][$i]; + } + else { + //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { + $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); + $accyt=$yscale->Translate($accy_neg); + $accy_neg+=$this->plots[$j]->coords[0][$i]; + } + + $xt=$xscale->Translate($i); + + if( $this->abswidth > -1 ) + $abswidth=$this->abswidth; + else + $abswidth=round($this->width*$xscale->scale_factor,0); + + $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); + + if( $this->bar_shadow ) { + $ssh = $this->bar_shadow_hsize; + $ssv = $this->bar_shadow_vsize; + + // We must also differ if we are a positive or negative bar. + if( $j === 0 ) { + // This gets extra complicated since we have to + // see all plots to see if we are negative. It could + // for example be that all plots are 0 until the very + // last one. We therefore need to save the initial setup + // for both the negative and positive case + + // In case the final bar is positive + $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; + $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; + + // In case the final bar is negative + $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; + $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; + $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; + $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; + } + + if( $j === $this->nbrplots-1 ) { + // If this is the last plot of the bar and + // the total value is larger than 0 then we + // add the shadow. + if( is_array($this->bar_shadow_color) ) { + $numcolors = count($this->bar_shadow_color); + if( $numcolors == 0 ) { + JpGraphError::Raise('You have specified an empty array for shadow colors in the bar plot.'); + } + $img->PushColor($this->bar_shadow_color[$i % $numcolors]); + } + else { + $img->PushColor($this->bar_shadow_color); + } + + if( $accy > 0 ) { + $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; + $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; + $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; + $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; + $img->FilledPolygon($sp,4); + } + elseif( $accy_neg < 0 ) { + $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; + $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; + $img->FilledPolygon($nsp,4); + } + $img->PopColor(); + } + } + + + // If value is NULL or 0, then don't draw a bar at all + if ($this->plots[$j]->coords[0][$i] == 0 ) continue; + + if( $this->plots[$j]->grad ) { + $grad = new Gradient($img); + $grad->FilledRectangle( + $pts[2],$pts[3], + $pts[6],$pts[7], + $this->plots[$j]->grad_fromcolor, + $this->plots[$j]->grad_tocolor, + $this->plots[$j]->grad_style); + } else { + if (is_array($this->plots[$j]->fill_color) ) { + $numcolors = count($this->plots[$j]->fill_color); + $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); + } + else { + $img->SetColor($this->plots[$j]->fill_color); + } + $img->FilledPolygon($pts); + $img->SetColor($this->plots[$j]->color); + } + + // Stroke the pattern + if( $this->plots[$j]->iPattern > -1 ) { + if( $pattern===NULL ) + $pattern = new RectPatternFactory(); + + $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); + $prect->SetDensity($this->plots[$j]->iPatternDensity); + $prect->SetPos(new Rectangle($pts[2],$pts[3],$pts[4]-$pts[0]+1,$pts[1]-$pts[3]+1)); + $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.= 'csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\""; + if( !empty($this->plots[$j]->csimalts[$i]) ) { + $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); + $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; + } + $this->csimareas .= ">\n"; + } + } + + $pts[] = $pts[0]; + $pts[] = $pts[1]; + $img->Polygon($pts); + } + + // Draw labels for each acc.bar + + $x=$pts[2]+($pts[4]-$pts[2])/2; + $y=$yscale->Translate($accy); + if($this->bar_shadow) $x += $ssh; + $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); + $y = $accyt-($accyt-$yt)/2; + $accy+=$this->plots[$j]->coords[0][$i]; + } else { + $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); + $accyt=$yscale->Translate($accy_neg); + //$y=0; + $accy_neg+=$this->plots[$j]->coords[0][$i]; + $y = $accyt-($accyt-$yt)/2; // TODO : Check this fix + } + $this->plots[$j]->value->SetAlign("center","center"); + $this->plots[$j]->value->SetMargin(0); + $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); + } - } - return true; + } + return true; } } // Class Index: include/jpgraph/jpgraph_gradient.php =================================================================== RCS file: /repository/docweb/include/jpgraph/jpgraph_gradient.php,v retrieving revision 1.1 diff -u -r1.1 jpgraph_gradient.php --- include/jpgraph/jpgraph_gradient.php 4 Aug 2004 17:14:55 -0000 1.1 +++ include/jpgraph/jpgraph_gradient.php 4 Dec 2006 23:06:55 -0000 @@ -1,12 +1,12 @@ img = $img; + $this->img = $img; } function SetNumColors($aNum) { - $this->numcolors=$aNum; + $this->numcolors=$aNum; } //--------------- -// PUBLIC METHODS +// 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? + // ($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 = 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 = 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 = abs($yb-$yt)/2; - $delta = $yb >= $yt ? 1 : -1; - $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); - for($y=$yt, $i=0; $i < $steps; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($xl,$y,$xr,$y); - $y += $delta; - } - --$i; - if( abs($yb-$yt) % 2 == 1 ) --$steps; - for($j=0; $j < $steps; ++$j, --$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($xl,$y,$xr,$y); - $y += $delta; - } - $this->img->Line($xl,$y,$xr,$y); - break; - - case GRAD_MIDVER: - $steps = round(abs($xr-$xl)/2); - $delta = $xr>=$xl ? 1 : -1; - $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); - for($x=$xl, $i=0; $i < $steps; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - --$i; - if( abs($xr-$xl) % 2 == 1 ) --$steps; - for($j=0; $j < $steps; ++$j, --$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - $this->img->Line($x,$yb,$x,$yt); - break; - - case GRAD_WIDE_MIDVER: - $diff = round(abs($xr-$xl)); - $steps = floor(abs($diff)/3); - $firststep = $diff - 2*$steps ; - $delta = $xr >= $xl ? 1 : -1; - $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); - for($x=$xl, $i=0; $i < $firststep; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - --$i; - $this->img->current_color = $colors[$i]; - for($j=0; $j< $steps; ++$j) { - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - - for($j=0; $j < $steps; ++$j, --$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - break; - - case GRAD_WIDE_MIDHOR: - $diff = round(abs($yb-$yt)); - $steps = floor(abs($diff)/3); - $firststep = $diff - 2*$steps ; - $delta = $yb >= $yt? 1 : -1; - $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); - for($y=$yt, $i=0; $i < $firststep; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($xl,$y,$xr,$y); - $y += $delta; - } - --$i; - $this->img->current_color = $colors[$i]; - for($j=0; $j < $steps; ++$j) { - $this->img->Line($xl,$y,$xr,$y); - $y += $delta; - } - for($j=0; $j < $steps; ++$j, --$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($xl,$y,$xr,$y); - $y += $delta; - } - break; - - case GRAD_LEFT_REFLECTION: - $steps1 = round(0.3*abs($xr-$xl)); - $delta = $xr>=$xl ? 1 : -1; - - $this->GetColArray($from_color.':1.3',$to_color,$steps1,$colors,$this->numcolors); - for($x=$xl, $i=0; $i < $steps1; ++$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); - for($i=0; $i < $steps; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - break; - - case GRAD_RIGHT_REFLECTION: - $steps1 = round(0.7*abs($xr-$xl)); - $delta = $xr>=$xl ? 1 : -1; - - $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors); - for($x=$xl, $i=0; $i < $steps1; ++$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.':1.3',$steps,$colors,$this->numcolors); - for($i=0; $i < $steps; ++$i) { - $this->img->current_color = $colors[$i]; - $this->img->Line($x,$yb,$x,$yt); - $x += $delta; - } - break; - - - case GRAD_CENTER: - $steps = floor(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; - for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy ; ++$x, ++$y, --$x2, --$y2, ++$i) { - assert( $i < count($colors)); - $this->img->current_color = $colors[$i]; - $this->img->Rectangle($x,$y,$x2,$y2); - } - $this->img->Line($x,$y,$x2,$y2); - break; - - default: - die("JpGraph Error: Unknown gradient style (=$style)."); - break; - } + switch( $style ) { + case GRAD_VER: + $steps = 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 = 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 = abs($yb-$yt)/2; + $delta = $yb >= $yt ? 1 : -1; + $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); + for($y=$yt, $i=0; $i < $steps; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($xl,$y,$xr,$y); + $y += $delta; + } + --$i; + if( abs($yb-$yt) % 2 == 1 ) --$steps; + for($j=0; $j < $steps; ++$j, --$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($xl,$y,$xr,$y); + $y += $delta; + } + $this->img->Line($xl,$y,$xr,$y); + break; + + case GRAD_MIDVER: + $steps = round(abs($xr-$xl)/2); + $delta = $xr>=$xl ? 1 : -1; + $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); + for($x=$xl, $i=0; $i < $steps; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + --$i; + if( abs($xr-$xl) % 2 == 1 ) --$steps; + for($j=0; $j < $steps; ++$j, --$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + $this->img->Line($x,$yb,$x,$yt); + break; + + case GRAD_WIDE_MIDVER: + $diff = round(abs($xr-$xl)); + $steps = floor(abs($diff)/3); + $firststep = $diff - 2*$steps ; + $delta = $xr >= $xl ? 1 : -1; + $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); + for($x=$xl, $i=0; $i < $firststep; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + --$i; + $this->img->current_color = $colors[$i]; + for($j=0; $j< $steps; ++$j) { + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + + for($j=0; $j < $steps; ++$j, --$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + break; + + case GRAD_WIDE_MIDHOR: + $diff = round(abs($yb-$yt)); + $steps = floor(abs($diff)/3); + $firststep = $diff - 2*$steps ; + $delta = $yb >= $yt? 1 : -1; + $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); + for($y=$yt, $i=0; $i < $firststep; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($xl,$y,$xr,$y); + $y += $delta; + } + --$i; + $this->img->current_color = $colors[$i]; + for($j=0; $j < $steps; ++$j) { + $this->img->Line($xl,$y,$xr,$y); + $y += $delta; + } + for($j=0; $j < $steps; ++$j, --$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($xl,$y,$xr,$y); + $y += $delta; + } + break; + + case GRAD_LEFT_REFLECTION: + $steps1 = round(0.3*abs($xr-$xl)); + $delta = $xr>=$xl ? 1 : -1; + + $this->GetColArray($from_color.':1.3',$to_color,$steps1,$colors,$this->numcolors); + for($x=$xl, $i=0; $i < $steps1; ++$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); + for($i=0; $i < $steps; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + break; + + case GRAD_RIGHT_REFLECTION: + $steps1 = round(0.7*abs($xr-$xl)); + $delta = $xr>=$xl ? 1 : -1; + + $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors); + for($x=$xl, $i=0; $i < $steps1; ++$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.':1.3',$steps,$colors,$this->numcolors); + for($i=0; $i < $steps; ++$i) { + $this->img->current_color = $colors[$i]; + $this->img->Line($x,$yb,$x,$yt); + $x += $delta; + } + break; + + + case GRAD_CENTER: + $steps = floor(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; + for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy ; ++$x, ++$y, --$x2, --$y2, ++$i) { + assert( $i < count($colors)); + $this->img->current_color = $colors[$i]; + $this->img->Rectangle($x,$y,$x2,$y2); + } + $this->img->Line($x,$y,$x2,$y2); + break; + + default: + die("JpGraph Error: Unknown gradient style (=$style)."); + break; + } } // Fill a special case of a polygon with a flat bottom @@ -227,96 +227,96 @@ // routine. It assumes that the bottom is flat (like a drawing // of a mountain) function FilledFlatPolygon($pts,$from_color,$to_color) { - if( count($pts) == 0 ) return; - - $maxy=$pts[1]; - $miny=$pts[1]; - $n = count($pts) ; - for( $i=0, $idx=0; $i < $n; $i += 2) { - $x = round($pts[$i]); - $y = round($pts[$i+1]); - $miny = min($miny,$y); - $maxy = max($maxy,$y); - } - - $colors = array(); - $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors); - for($i=$miny, $idx=0; $i <= $maxy; ++$i ) { - $colmap[$i] = $colors[$idx++]; - } - - $n = count($pts)/2 ; - $idx = 0 ; - while( $idx < $n-1 ) { - $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1])); - $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1])); - - // Find the largest rectangle we can fill - $y = max($p1[1],$p2[1]) ; - for($yy=$maxy; $yy > $y; --$yy) { - $this->img->current_color = $colmap[$yy]; - $this->img->Line($p1[0],$yy,$p2[0]-1,$yy); - } - - if( $p1[1] == $p2[1] ) continue; - - // Fill the rest using lines (slow...) - $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]); - $x1 = $p1[0]; - $x2 = $p2[0]; //-1; - $start = $y; - if( $p1[1] > $p2[1] ) { - while( $y >= $p2[1] ) { - $x1=$slope*($start-$y)+$p1[0]; - $this->img->current_color = $colmap[$y]; - $this->img->Line($x1,$y,$x2,$y); - --$y; - } - } - else { - while( $y >= $p1[1] ) { - $x2=$p2[0]+$slope*($start-$y); - $this->img->current_color = $colmap[$y]; - $this->img->Line($x1,$y,$x2,$y); - --$y; - } - } - } + if( count($pts) == 0 ) return; + + $maxy=$pts[1]; + $miny=$pts[1]; + $n = count($pts) ; + for( $i=0, $idx=0; $i < $n; $i += 2) { + $x = round($pts[$i]); + $y = round($pts[$i+1]); + $miny = min($miny,$y); + $maxy = max($maxy,$y); + } + + $colors = array(); + $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors); + for($i=$miny, $idx=0; $i <= $maxy; ++$i ) { + $colmap[$i] = $colors[$idx++]; + } + + $n = count($pts)/2 ; + $idx = 0 ; + while( $idx < $n-1 ) { + $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1])); + $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1])); + + // Find the largest rectangle we can fill + $y = max($p1[1],$p2[1]) ; + for($yy=$maxy; $yy > $y; --$yy) { + $this->img->current_color = $colmap[$yy]; + $this->img->Line($p1[0],$yy,$p2[0]-1,$yy); + } + + if( $p1[1] == $p2[1] ) continue; + + // Fill the rest using lines (slow...) + $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]); + $x1 = $p1[0]; + $x2 = $p2[0]; //-1; + $start = $y; + if( $p1[1] > $p2[1] ) { + while( $y >= $p2[1] ) { + $x1=$slope*($start-$y)+$p1[0]; + $this->img->current_color = $colmap[$y]; + $this->img->Line($x1,$y,$x2,$y); + --$y; + } + } + else { + while( $y >= $p1[1] ) { + $x2=$p2[0]+$slope*($start-$y); + $this->img->current_color = $colmap[$y]; + $this->img->Line($x1,$y,$x2,$y); + --$y; + } + } + } } //--------------- -// PRIVATE METHODS +// 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; - } - } + 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 ?> Index: include/jpgraph/jpgraph_pie.php =================================================================== RCS file: /repository/docweb/include/jpgraph/jpgraph_pie.php,v retrieving revision 1.1 diff -u -r1.1 jpgraph_pie.php --- include/jpgraph/jpgraph_pie.php 4 Aug 2004 17:14:55 -0000 1.1 +++ include/jpgraph/jpgraph_pie.php 4 Dec 2006 23:06:56 -0000 @@ -1,12 +1,12 @@ 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)); + "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 @@ -51,532 +51,532 @@ var $legendcsimtargets = array(); var $legendcsimalts = array(); var $adjusted_data = array(); - + //--------------- // 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->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%%'); } //--------------- -// PUBLIC METHODS +// PUBLIC METHODS function SetCenter($x,$y=0.5) { - $this->posx = $x; - $this->posy = $y; + $this->posx = $x; + $this->posy = $y; } function SetColor($aColor) { - $this->color = $aColor; + $this->color = $aColor; } - + function SetSliceColors($aColors) { - $this->setslicecolors = $aColors; + $this->setslicecolors = $aColors; } - + function SetShadow($aColor='darkgray',$aDropWidth=4) { - $this->ishadowcolor = $aColor; - $this->ishadowdrop = $aDropWidth; + $this->ishadowcolor = $aColor; + $this->ishadowdrop = $aDropWidth; } function SetCSIMTargets($targets,$alts=null) { - $this->csimtargets=array_reverse($targets); - if( is_array($alts) ) - $this->csimalts=array_reverse($alts); + $this->csimtargets=array_reverse($targets); + if( is_array($alts) ) + $this->csimalts=array_reverse($alts); } - + function GetCSIMareas() { - return $this->csimareas; + 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; + 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; + $sa = 2*M_PI - $sa; + $ea = 2*M_PI - $ea; - //add coordinates of the centre to the map - $coords = "$xc, $yc"; + //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(($radius*cos($ea))+$xc); - $yp = floor($yc-$radius*sin($ea)); - $coords.= ", $xp, $yp"; - - //add coordinates every 0.2 radians - $a=$ea+0.2; - 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 .= "csimtargets[$i]."\""; - if( !empty($this->csimalts[$i]) ) { - $tmp=sprintf($this->csimalts[$i],$this->data[$i]); - $this->csimareas .= " alt=\"$tmp\" title=\"$tmp\""; - } - $this->csimareas .= ">\n"; - } + //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; + 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 .= "csimtargets[$i]."\""; + if( !empty($this->csimalts[$i]) ) { + $tmp=sprintf($this->csimalts[$i],$this->data[$i]); + $this->csimareas .= " alt=\"$tmp\" title=\"$tmp\""; + } + $this->csimareas .= ">\n"; + } } - + function SetTheme($aTheme) { - if( in_array($aTheme,array_keys($this->themearr)) ) - $this->theme = $aTheme; - else - JpGraphError::Raise("PiePLot::SetTheme() Unknown theme: $aTheme"); + if( in_array($aTheme,array_keys($this->themearr)) ) + $this->theme = $aTheme; + else + JpGraphError::Raise("PiePLot::SetTheme() Unknown theme: $aTheme"); } - + function ExplodeSlice($e,$radius=20) { - if( ! is_integer($e) ) - JpGraphError::Raise('Argument to PiePlot::ExplodeSlice() must be an integer'); - $this->explode_radius[$e]=$radius; + if( ! is_integer($e) ) + JpGraphError::Raise('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; + $this->explode_all=true; + $this->explode_r = $radius; } function Explode($aExplodeArr) { - if( !is_array($aExplodeArr) ) { - JpGraphError::Raise("Argument to PiePlot::Explode() must be an array with integer distances."); - } - $this->explode_radius = $aExplodeArr; + if( !is_array($aExplodeArr) ) { + JpGraphError::Raise("Argument to PiePlot::Explode() must be an array with integer distances."); + } + $this->explode_radius = $aExplodeArr; } function SetStartAngle($aStart) { - if( $aStart < 0 || $aStart > 360 ) { - JpGraphError::Raise('Slice start angle must be between 0 and 360 degrees.'); - } - $this->startangle = 360-$aStart; - $this->startangle *= M_PI/180; + if( $aStart < 0 || $aStart > 360 ) { + JpGraphError::Raise('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::Raise('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.'); + JpGraphError::Raise('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::Raise("PiePlot::SetSize() Radius for pie must either be specified as a fraction + if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) ) + $this->radius = $aSize; + else + JpGraphError::Raise("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::Raise('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.'); + JpGraphError::Raise('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.'); } - + // Set label arrays function SetLegends($aLegend) { - $this->legends = $aLegend; + $this->legends = $aLegend; } // Set text labels for slices function SetLabels($aLabels,$aLblPosAdj="auto") { - $this->labels = array_reverse($aLabels); - $this->ilabelposadj=$aLblPosAdj; + $this->labels = array_reverse($aLabels); + $this->ilabelposadj=$aLblPosAdj; } function SetLabelPos($aLblPosAdj) { - $this->ilabelposadj=$aLblPosAdj; + $this->ilabelposadj=$aLblPosAdj; } - + // Should we display actual value or percentage? function SetLabelType($t) { - if( $t < 0 || $t > 2 ) - JpGraphError::Raise("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t)."); - $this->labeltype=$t; + if( $t < 0 || $t > 2 ) + JpGraphError::Raise("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t)."); + $this->labeltype=$t; } function SetValueType($aType) { - $this->SetLabelType($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; + $this->pie_border = $exterior; + $this->pie_interior_border = $interior; } - + // Setup the legends 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( get_class($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 && get_class($this)==='pieplot' ) { - $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::Raise("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( $this->labeltype==0 ) { - $l = sprintf($l,100*$this->data[$i]/$sum); - $alt = sprintf($this->csimalts[$i],$this->data[$i]); - - } - elseif( $this->labeltype == 1) { - $l = sprintf($l,$this->data[$i]); - $alt = sprintf($this->csimalts[$i],$this->data[$i]); - - } - else { - $l = sprintf($l,$this->adjusted_data[$i]); - $alt = sprintf($this->csimalts[$i],$this->adjusted_data[$i]); - } - - - if( $this->setslicecolors==null ) { - $graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0, - $this->csimtargets[$i],$alt); - } - else { - $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0, - $this->csimtargets[$i],$alt); - } - } + $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( get_class($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 && get_class($this)==='pieplot' ) { + $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::Raise("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( $this->labeltype==0 ) { + $l = sprintf($l,100*$this->data[$i]/$sum); + $alt = sprintf($this->csimalts[$i],$this->data[$i]); + + } + elseif( $this->labeltype == 1) { + $l = sprintf($l,$this->data[$i]); + $alt = sprintf($this->csimalts[$i],$this->data[$i]); + + } + else { + $l = sprintf($l,$this->adjusted_data[$i]); + $alt = sprintf($this->csimalts[$i],$this->adjusted_data[$i]); + } + + + if( $this->setslicecolors==null ) { + $graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0, + $this->csimtargets[$i],$alt); + } + else { + $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0, + $this->csimtargets[$i],$alt); + } + } } - + // 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; + $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::Raise("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( $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; - - $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; - - $img->CakeSlice($xcm,$ycm,$radius,$radius, - $angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor); - - } - } - - $accsum=0; - $angle2 = $this->startangle; - $img->SetColor($this->color); - for($i=0; $sum>0 && $i < $n; ++$i) { - $j = $n-$i-1; - if( empty($this->explode_radius[$j]) ) - $this->explode_radius[$j]=0; - $d = $this->data[$i]; - $angle1 = $angle2; - $accsum += $d; - $angle2 = $this->startangle+2*M_PI*$accsum/$sum; - $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); - - if( $d == 0 ) continue; - - if( $this->setslicecolors==null ) - $slicecolor=$colors[$ta[$i%$numcolors]]; - else - $slicecolor=$this->setslicecolors[$i%$numcolors]; - - if( $this->pie_interior_border && $aaoption===0 ) - $img->SetColor($this->color); - else - $img->SetColor($slicecolor); - - $arccolor = $this->pie_border && $aaoption===0 ? $this->color : ""; - - $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale; - $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale; - - if( $aaoption !== 2 ) { - $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1, - $angle1*180/M_PI,$angle2*180/M_PI,$slicecolor,$arccolor); - } - - if( $this->csimtargets && $aaoption !== 1 ) - $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2); - } - - // Format the titles for each slice - 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); - } + // 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::Raise("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( $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; + + $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; + + $img->CakeSlice($xcm,$ycm,$radius,$radius, + $angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor); + + } + } + + $accsum=0; + $angle2 = $this->startangle; + $img->SetColor($this->color); + for($i=0; $sum>0 && $i < $n; ++$i) { + $j = $n-$i-1; + if( empty($this->explode_radius[$j]) ) + $this->explode_radius[$j]=0; + $d = $this->data[$i]; + $angle1 = $angle2; + $accsum += $d; + $angle2 = $this->startangle+2*M_PI*$accsum/$sum; + $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); + + if( $d == 0 ) continue; + + if( $this->setslicecolors==null ) + $slicecolor=$colors[$ta[$i%$numcolors]]; + else + $slicecolor=$this->setslicecolors[$i%$numcolors]; + + if( $this->pie_interior_border && $aaoption===0 ) + $img->SetColor($this->color); + else + $img->SetColor($slicecolor); + + $arccolor = $this->pie_border && $aaoption===0 ? $this->color : ""; + + $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale; + $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale; + + if( $aaoption !== 2 ) { + $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1, + $angle1*180/M_PI,$angle2*180/M_PI,$slicecolor,$arccolor); + } + + if( $this->csimtargets && $aaoption !== 1 ) + $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2); + } + + // Format the titles for each slice + 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 +// PRIVATE METHODS function StrokeAllLabels($img,$xc,$yc,$radius) { - $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-$i-1]); - } + $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-$i-1]); + } } // Position the labels of each slice function StrokeLabel($label,$img,$xc,$yc,$a,$r) { - // Default value - if( $this->ilabelposadj === 'auto' ) - $this->ilabelposadj = 0.65; - - // 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)); - - 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); - } - } + // Default value + if( $this->ilabelposadj === 'auto' ) + $this->ilabelposadj = 0.65; + + // 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)); + + 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 @@ -586,162 +586,162 @@ // filled circle in the center //=================================================== class PiePlotC extends PiePlot { - var $imidsize=0.5; // Fraction of total width + var $imidsize=0.5; // Fraction of total width var $imidcolor='white'; var $midtitle=''; var $middlecsimtarget="",$middlecsimalt=""; function PiePlotC($data,$aCenterTitle='') { - parent::PiePlot($data); - $this->midtitle = new Text(); - $this->midtitle->ParagraphAlign('center'); + 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 ; + $this->midtitle->Set($aTitle); + $this->imidsize = $aSize ; + $this->imidcolor = $aColor ; } function SetMidTitle($aTitle) { - $this->midtitle->Set($aTitle); + $this->midtitle->Set($aTitle); } function SetMidSize($aSize) { - $this->imidsize = $aSize ; + $this->imidsize = $aSize ; } function SetMidColor($aColor) { - $this->imidcolor = $aColor ; + $this->imidcolor = $aColor ; } function SetMidCSIM($aTarget,$aAlt) { - $this->middlecsimtarget = $aTarget; - $this->middlecsimalt = $aAlt; + $this->middlecsimtarget = $aTarget; + $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; + 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; + $sa = 2*M_PI - $sa; + $ea = 2*M_PI - $ea; - // 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; - 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 .= "csimtargets[$i]."\""; - if( !empty($this->csimalts[$i]) ) { - $tmp=sprintf($this->csimalts[$i],$this->data[$i]); - $this->csimareas .= " alt=\"$tmp\" title=\"$tmp\""; - } - $this->csimareas .= ">\n"; - } + // 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; + 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 .= "csimtargets[$i]."\""; + if( !empty($this->csimalts[$i]) ) { + $tmp=sprintf($this->csimalts[$i],$this->data[$i]); + $this->csimareas .= " alt=\"$tmp\" title=\"$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; + // 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); + $xc = round($this->posx*$img->width); + $yc = round($this->posy*$img->height); - $radius = floor($this->radius * min($img->width,$img->height)) ; + $radius = floor($this->radius * min($img->width,$img->height)) ; - if( $this->imidsize > 0 && $aaoption !== 2 ) { + 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)); - } + 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)); + $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( $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( !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); - } + 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) { - $this->csimareas .= "middlecsimtarget."\""; - if( !empty($this->middlecsimalt) ) { - $tmp = $this->middlecsimalt; - $this->csimareas .= " alt=\"$tmp\" title=\"$tmp\""; - } - $this->csimareas .= ">\n"; + $this->csimareas .= "middlecsimtarget."\""; + if( !empty($this->middlecsimalt) ) { + $tmp = $this->middlecsimalt; + $this->csimareas .= " alt=\"$tmp\" title=\"$tmp\""; + } + $this->csimareas .= ">\n"; } function StrokeLabel($label,$img,$xc,$yc,$a,$r) { - if( $this->ilabelposadj === 'auto' ) - $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize; + if( $this->ilabelposadj === 'auto' ) + $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize; - parent::StrokeLabel($label,$img,$xc,$yc,$a,$r); + parent::StrokeLabel($label,$img,$xc,$yc,$a,$r); } @@ -753,217 +753,217 @@ // Description: //=================================================== class PieGraph extends Graph { - var $posx, $posy, $radius; - var $legends=array(); + 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)); + $this->Graph($width,$height,$cachedName,$timeout,$inline); + $this->posx=$width/2; + $this->posy=$height/2; + $this->SetColor(array(255,255,255)); } //--------------- -// PUBLIC METHODS +// PUBLIC METHODS function Add($aObj) { - if( is_array($aObj) && count($aObj) > 0 ) - $cl = get_class($aObj[0]); - else - $cl = get_class($aObj); - - if( $cl == 'text' ) - $this->AddText($aObj); - elseif( $cl == 'iconplot' ) - $this->AddIcon($aObj); - else - $this->plots[] = $aObj; + if( is_array($aObj) && count($aObj) > 0 ) + $cl = get_class($aObj[0]); + else + $cl = get_class($aObj); + + if( $cl == 'text' ) + $this->AddText($aObj); + elseif( $cl == 'iconplot' ) + $this->AddIcon($aObj); + else + $this->plots[] = $aObj; } function SetAntiAliasing($aFlg=true) { - $this->pieaa = $aFlg; + $this->pieaa = $aFlg; } - + function SetColor($c) { - $this->SetMarginColor($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); - for ($i=0; $iimg->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); - for ($j=0; $jimg->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]); - - } - } - } + $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); + for ($i=0; $iimg->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); + for ($j=0; $jimg->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 - // imahe to do the anti aliasing - $ni = count($this->iIcons); - for($i=0; $i < $ni; ++$i) { - $this->iIcons[$i]->iScale *= 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 { - - if( !$_csim ) { - if( $this->background_image != "" ) { - $this->StrokeFrameBackground(); - } - else { - $this->StrokeFrame(); - } - } - - $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); - - if( !$_csim ) { - $this->StrokeTitles(); - - // 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); - } - } + // 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 + // imahe to do the anti aliasing + $ni = count($this->iIcons); + for($i=0; $i < $ni; ++$i) { + $this->iIcons[$i]->iScale *= 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 { + + if( !$_csim ) { + if( $this->background_image != "" ) { + $this->StrokeFrameBackground(); + } + else { + $this->StrokeFrame(); + } + } + + $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); + + if( !$_csim ) { + $this->StrokeTitles(); + + // 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 Index: include/jpgraph/jpgraph_pie3d.php =================================================================== RCS file: /repository/docweb/include/jpgraph/jpgraph_pie3d.php,v retrieving revision 1.1 diff -u -r1.1 jpgraph_pie3d.php --- include/jpgraph/jpgraph_pie3d.php 4 Aug 2004 17:14:55 -0000 1.1 +++ include/jpgraph/jpgraph_pie3d.php 4 Dec 2006 23:06:57 -0000 @@ -1,12 +1,12 @@ 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%%'); + $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 - +// PUBLIC METHODS + // Set label arrays function SetLegends($aLegend) { - $this->legends = array_reverse($aLegend); + $this->legends = array_reverse($aLegend); } function SetSliceColors($aColors) { - $this->setslicecolors = $aColors; + $this->setslicecolors = $aColors; } function Legend(&$aGraph) { - parent::Legend($aGraph); - $aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol); + parent::Legend($aGraph); + $aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol); } function SetCSIMTargets($targets,$alts=null) { - $this->csimtargets = $targets; - $this->csimalts = $alts; + $this->csimtargets = $targets; + $this->csimalts = $alts; } // Should the slices be separated by a line? If color is specified as "" no line // will be used to separate pie slices. function SetEdge($aColor,$aWeight=1) { - $this->edgecolor = $aColor; - $this->edgeweight = $aWeight; + $this->edgecolor = $aColor; + $this->edgeweight = $aWeight; } // Specify projection angle for 3D in degrees // Must be between 20 and 70 degrees function SetAngle($a) { - if( $a<5 || $a>90 ) - JpGraphError::Raise("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees."); - else - $this->angle = $a; + if( $a<5 || $a>90 ) + JpGraphError::Raise("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; + $sa *= M_PI/180; + $ea *= M_PI/180; - //add coordinates of the centre to the map - $coords = "$xc, $yc"; + //add coordinates of the centre to the map + $coords = "$xc, $yc"; - //add coordinates of the first point on the arc to the map - $xp = floor($width*cos($sa)/2+$xc); - $yp = floor($yc-$height*sin($sa)/2); - $coords.= ", $xp, $yp"; - - //If on the front half, add the thickness offset - if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { - $yp = floor($yp+$thick); - $coords.= ", $xp, $yp"; - } - - //add coordinates every 0.2 radians - $a=$sa+0.2; - while ($a<$ea) { - $xp = floor($width*cos($a)/2+$xc); - if ($a >= M_PI && $a <= 2*M_PI*1.01) { - $yp = floor($yc-($height*sin($a)/2)+$thick); - } else { - $yp = floor($yc-$height*sin($a)/2); - } - $coords.= ", $xp, $yp"; - $a += 0.2; - } - - //Add the last point on the arc - $xp = floor($width*cos($ea)/2+$xc); - $yp = floor($yc-$height*sin($ea)/2); - - - if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { - $coords.= ", $xp, ".floor($yp+$thick); - } - $coords.= ", $xp, $yp"; - $alt=''; - if( !empty($this->csimalts[$i]) ) { - $tmp=sprintf($this->csimalts[$i],$this->data[$i]); - $alt="alt=\"$tmp\" title=\"$tmp\""; - } - if( !empty($this->csimtargets[$i]) ) - $this->csimareas .= "csimtargets[$i]."\" $alt>\n"; + //add coordinates of the first point on the arc to the map + $xp = floor($width*cos($sa)/2+$xc); + $yp = floor($yc-$height*sin($sa)/2); + $coords.= ", $xp, $yp"; + + //If on the front half, add the thickness offset + if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { + $yp = floor($yp+$thick); + $coords.= ", $xp, $yp"; + } + + //add coordinates every 0.2 radians + $a=$sa+0.2; + while ($a<$ea) { + $xp = floor($width*cos($a)/2+$xc); + if ($a >= M_PI && $a <= 2*M_PI*1.01) { + $yp = floor($yc-($height*sin($a)/2)+$thick); + } else { + $yp = floor($yc-$height*sin($a)/2); + } + $coords.= ", $xp, $yp"; + $a += 0.2; + } + + //Add the last point on the arc + $xp = floor($width*cos($ea)/2+$xc); + $yp = floor($yc-$height*sin($ea)/2); + + + if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { + $coords.= ", $xp, ".floor($yp+$thick); + } + $coords.= ", $xp, $yp"; + $alt=''; + if( !empty($this->csimalts[$i]) ) { + $tmp=sprintf($this->csimalts[$i],$this->data[$i]); + $alt="alt=\"$tmp\" title=\"$tmp\""; + } + if( !empty($this->csimtargets[$i]) ) + $this->csimareas .= "csimtargets[$i]."\" $alt>\n"; } function SetLabels($aLabels,$aLblPosAdj="auto") { - $this->labels = $aLabels; - $this->ilabelposadj=$aLblPosAdj; + $this->labels = $aLabels; + $this->ilabelposadj=$aLblPosAdj; } - + // Distance from the pie to the labels function SetLabelMargin($m) { - assert($m>0 && $m<1); - $this->labelmargin=$m; + assert($m>0 && $m<1); + $this->labelmargin=$m; } - + // Show a thin line from the pie to the label for a specific slice function ShowLabelHint($f=true) { - $this->showlabelhint=$f; + $this->showlabelhint=$f; } - + // Set color of hint line to label for each slice function SetLabelHintColor($c) { - $this->labelhintcolor=$c; + $this->labelhintcolor=$c; } function SetHeight($aHeight) { @@ -151,751 +151,751 @@ // 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; + // 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; + 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::Raise('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(); + + // 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::Raise('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::Raise('Slice start angle must be between 0 and 360 degrees.'); - } - $this->startangle = $aStart; + if( $aStart < 0 || $aStart > 360 ) { + JpGraphError::Raise('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) { + $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; $ilabeltype == 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; $iexplode_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::Raise("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); - //--------------------------------------------------------------------------- - // 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; $ilabeltype == 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; $iexplode_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::Raise("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::Raise("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); - } - ++$cnt; - } + $j++; + if( $j >= $n ) $j=0; + if( $cnt > $n ) { + JpGraphError::Raise("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::Raise("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; - for($i=0; $i < count($data); ++$i ) { - $la = $labeldata[$i][0]; - $x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin); - $y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin); - 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(); + $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::Raise("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; + for($i=0; $i < count($data); ++$i ) { + $la = $labeldata[$i][0]; + $x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin); + $y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin); + 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; + $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; - 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) ) { + $img->SetColor($edgecolor); + $img->Polygon($p); - if($sa < M_PI && $ea > M_PI) - $sa = M_PI; + // 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 < 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); - } - } + 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); + $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::Raise("Width for 3D Pie is 0. Specify a size > 0"); - exit(); - } - - // 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); - } + // 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::Raise("Width for 3D Pie is 0. Specify a size > 0"); + exit(); + } + + // 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 +// PRIVATE METHODS // Position the labels of each slice function StrokeLabels($label,$img,$a,$xp,$yp,$z) { - $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); - 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); + $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); + 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); - */ + $img->SetColor('red'); + $img->Line($xp-10,$yp,$xp+10,$yp); + $img->Line($xp,$yp-10,$xp,$yp+10); + */ - $this->value->Stroke($img,$label,$x,$y); - } + $this->value->Stroke($img,$label,$x,$y); + } } // Class /* EOF */ Index: include/jpgraph/jpgraph_plotband.php =================================================================== RCS file: /repository/docweb/include/jpgraph/jpgraph_plotband.php,v retrieving revision 1.1 diff -u -r1.1 jpgraph_plotband.php --- include/jpgraph/jpgraph_plotband.php 4 Aug 2004 17:14:55 -0000 1.1 +++ include/jpgraph/jpgraph_plotband.php 4 Dec 2006 23:06:57 -0000 @@ -1,17 +1,17 @@ x=$aX; - $this->y=$aY; - $this->w=$aWidth; - $this->h=$aHeight; - $this->xe=$aX+$aWidth-1; - $this->ye=$aY+$aHeight-1; + $this->x=$aX; + $this->y=$aY; + $this->w=$aWidth; + $this->h=$aHeight; + $this->xe=$aX+$aWidth-1; + $this->ye=$aY+$aHeight-1; } } @@ -47,53 +47,53 @@ var $weight; var $rect=null; var $doframe=true; - var $linespacing; // Line spacing in pixels + 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; + $this->color = $aColor; + $this->weight = $aWeight; } function SetBackground($aBackgroundColor) { - $this->iBackgroundColor=$aBackgroundColor; + $this->iBackgroundColor=$aBackgroundColor; } function SetPos(&$aRect) { - $this->rect = $aRect; + $this->rect = $aRect; } - + function ShowFrame($aShow=true) { - $this->doframe=$aShow; + $this->doframe=$aShow; } function SetDensity($aDens) { - if( $aDens < 1 || $aDens > 100 ) - JpGraphError::Raise(" 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; + if( $aDens < 1 || $aDens > 100 ) + JpGraphError::Raise(" 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::Raise(" No positions specified for pattern."); + if( $this->rect == null ) + JpGraphError::Raise(" 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); + 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); } } @@ -106,13 +106,13 @@ class RectPatternSolid extends RectPattern { function RectPatternSolid($aColor="black",$aWeight=1) { - parent::RectPattern($aColor,$aWeight); + 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); + $aImg->SetColor($this->color); + $aImg->FilledRectangle($this->rect->x,$this->rect->y, + $this->rect->xe,$this->rect->ye); } } @@ -121,20 +121,20 @@ // Implements horizontal line pattern //===================================================================== class RectPatternHor extends RectPattern { - + function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) { - parent::RectPattern($aColor,$aWeight); - $this->linespacing = $aLineSpacing; + 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; - } + $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; + } } } @@ -143,24 +143,24 @@ // Implements vertical line pattern //===================================================================== class RectPatternVert extends RectPattern { - var $linespacing=10; // Line spacing in pixels - + var $linespacing=10; // Line spacing in pixels + function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) { - parent::RectPattern($aColor,$aWeight); - $this->linespacing = $aLineSpacing; + 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; - } + $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; + } } } @@ -170,68 +170,68 @@ // Implements right diagonal pattern //===================================================================== class RectPatternRDiag extends RectPattern { - var $linespacing; // Line spacing in pixels - + var $linespacing; // Line spacing in pixels + function RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) { - parent::RectPattern($aColor,$aWeight); - $this->linespacing = $aLineSpacing; + 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; - } + // -------------------- + // | / / / / /| + // |/ / / / / | + // | / / / / | + // -------------------- + $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; + } } } @@ -240,63 +240,63 @@ // Implements left diagonal pattern //===================================================================== class RectPatternLDiag extends RectPattern { - var $linespacing; // Line spacing in pixels - + var $linespacing; // Line spacing in pixels + function RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) { - $this->linespacing = $aLineSpacing; - parent::RectPattern($aColor,$aWeight); + $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; - } + // -------------------- + // |\ \ \ \ \ | + // | \ \ \ \ \| + // | \ \ \ \ | + // |------------------| + $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; + } } } @@ -311,109 +311,109 @@ // converge. function RectPattern3DPlane($aColor="black",$aWeight=1) { - parent::RectPattern($aColor,$aWeight); - $this->SetDensity(10); // Slightly larger default + parent::RectPattern($aColor,$aWeight); + $this->SetDensity(10); // Slightly larger default } function SetHorizon($aHorizon) { - $this->alpha=$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; - } + // "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; + } } } @@ -425,30 +425,30 @@ 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); + 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); + $this->vert->SetOrder($aDepth); + $this->hor->SetOrder($aDepth); } function SetPos(&$aRect) { - parent::SetPos($aRect); - $this->vert->SetPos($aRect); - $this->hor->SetPos($aRect); + parent::SetPos($aRect); + $this->vert->SetPos($aRect); + $this->hor->SetPos($aRect); } function SetDensity($aDens) { - $this->vert->SetDensity($aDens); - $this->hor->SetDensity($aDens); + $this->vert->SetDensity($aDens); + $this->hor->SetDensity($aDens); } function DoPattern(&$aImg) { - $this->vert->DoPattern($aImg); - $this->hor->DoPattern($aImg); + $this->vert->DoPattern($aImg); + $this->hor->DoPattern($aImg); } } @@ -461,30 +461,30 @@ 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); + 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); + $this->left->SetOrder($aDepth); + $this->right->SetOrder($aDepth); } function SetPos(&$aRect) { - parent::SetPos($aRect); - $this->left->SetPos($aRect); - $this->right->SetPos($aRect); + parent::SetPos($aRect); + $this->left->SetPos($aRect); + $this->right->SetPos($aRect); } function SetDensity($aDens) { - $this->left->SetDensity($aDens); - $this->right->SetDensity($aDens); + $this->left->SetDensity($aDens); + $this->right->SetDensity($aDens); } function DoPattern(&$aImg) { - $this->left->DoPattern($aImg); - $this->right->DoPattern($aImg); + $this->left->DoPattern($aImg); + $this->right->DoPattern($aImg); } } @@ -495,38 +495,38 @@ //===================================================================== class RectPatternFactory { function RectPatternFactory() { - // Empty + // 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::Raise(" Unknown pattern specification ($aPattern)"); - } - return $obj; + 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::Raise(" Unknown pattern specification ($aPattern)"); + } + return $obj; } } @@ -543,88 +543,88 @@ 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::Raise('Min value for plotband is larger than specified max value. Please correct.'); - $this->dir = $aDir; - $this->min = $aMin; - $this->max = $aMax; - $this->depth=$aDepth; + $f = new RectPatternFactory(); + $this->prect = $f->Create($aPattern,$aColor,$aWeight); + if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) ) + JpGraphError::Raise('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); + assert( $this->prect != null ) ; + $this->prect->SetPos($aRect); } - + function ShowFrame($aFlag=true) { - $this->prect->ShowFrame($aFlag); + $this->prect->ShowFrame($aFlag); } // Set z-order. In front of pplot or in the back function SetOrder($aDepth) { - $this->depth=$aDepth; + $this->depth=$aDepth; } - + function SetDensity($aDens) { - $this->prect->SetDensity($aDens); + $this->prect->SetDensity($aDens); } - + function GetDir() { - return $this->dir; + return $this->dir; } - + function GetMin() { - return $this->min; + return $this->min; } - + function GetMax() { - return $this->max; + 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(); + 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); + + // 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(); + } + 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); + 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); } - } + } } } Index: include/rfc/rfc.php =================================================================== RCS file: /repository/docweb/include/rfc/rfc.php,v retrieving revision 1.22 diff -u -r1.22 rfc.php --- include/rfc/rfc.php 21 Jul 2006 16:16:29 -0000 1.22 +++ include/rfc/rfc.php 4 Dec 2006 23:06:58 -0000 @@ -525,8 +525,8 @@ } $this->id = sqlite_last_insert_rowid($dbh->connection); } - - if(isset($this->links) && $this->links !== null) { + + if(isset($this->links) && $this->links !== null) { ppLink::deleteAll($dbh, $this->id); foreach ($this->links as $link) { if (!empty($link->url)) { @@ -536,7 +536,7 @@ } } } - } + } if (!empty($this->comment)) { $this->comment->store($dbh, $this->id); unset($this->comment); @@ -922,7 +922,7 @@ { global $dbh; $sql = "SELECT *, timestamp FROM ".$table." WHERE pkg_prop_id = ".$proposalId." - AND user_handle='".$handle."' AND timestamp = ".$timestamp; + AND user_handle='".$handle."' AND timestamp = ".$timestamp; $res = $dbh->query($sql); if (DB::isError($res)) { return $res; @@ -955,7 +955,7 @@ } $sql = "INSERT INTO ".$this->table." (pkg_prop_id, user_handle, comment, timestamp) VALUES (".$proposalId.", ".$dbh->quoteSmart($this->user_handle).", - ".$dbh->quoteSmart($this->comment).", ".time().")"; + ".$dbh->quoteSmart($this->comment).", ".time().")"; $res = $dbh->query($sql); return $res; } @@ -967,7 +967,7 @@ return PEAR::raiseError("Inconsistant comment data. Can not delete comment."); } $sql = "DELETE FROM ".$this->table." WHERE user_handle = '".$this->user_handle."' - AND pkg_prop_id = ".$this->pkg_prop_id." AND timestamp = ".$this->timestamp; + AND pkg_prop_id = ".$this->pkg_prop_id." AND timestamp = ".$this->timestamp; $res = $dbh->query($sql); return true; } @@ -1005,7 +1005,7 @@ function get(&$dbh, $proposalId, $handle) { $sql = "SELECT *, timestamp FROM package_proposal_votes WHERE - pkg_prop_id = ".$proposalId." AND user_handle='".$handle."'"; + pkg_prop_id = ".$proposalId." AND user_handle='".$handle."'"; $res = $dbh->query($sql); if (DB::isError($res)) { return $res; @@ -1022,7 +1022,7 @@ function &getAll(&$dbh, $proposalId) { $sql = "SELECT *, timestamp FROM package_proposal_votes WHERE - pkg_prop_id = ".$proposalId." ORDER BY timestamp ASC"; + pkg_prop_id = ".$proposalId." ORDER BY timestamp ASC"; $res = $dbh->query($sql); if (DB::isError($res)) { return $res; @@ -1047,11 +1047,11 @@ $sql = "INSERT INTO package_proposal_votes (pkg_prop_id, user_handle, value, is_conditional, comment, reviews, timestamp) VALUES (".$proposalId.", - ".$dbh->quoteSmart($this->user_handle).", - ".$this->value.", ".(int)$this->is_conditional.", - ".$dbh->quoteSmart($this->comment).", - ".$dbh->quoteSmart(serialize($this->reviews)).", - ".time().")"; + ".$dbh->quoteSmart($this->user_handle).", + ".$this->value.", ".(int)$this->is_conditional.", + ".$dbh->quoteSmart($this->comment).", + ".$dbh->quoteSmart(serialize($this->reviews)).", + ".time().")"; $res = $dbh->query($sql); return $res; } @@ -1070,11 +1070,11 @@ function getSum($dbh, $proposalId) { $sql = "SELECT SUM(value) FROM package_proposal_votes WHERE - pkg_prop_id = ".$proposalId." GROUP BY pkg_prop_id"; + pkg_prop_id = ".$proposalId." GROUP BY pkg_prop_id"; $result = $dbh->getOne($sql); $res['all'] = (is_numeric($result)) ? $result : 0; $sql = "SELECT SUM(value) FROM package_proposal_votes WHERE - pkg_prop_id = ".$proposalId." AND is_conditional = 1 GROUP BY pkg_prop_id"; + pkg_prop_id = ".$proposalId." AND is_conditional = 1 GROUP BY pkg_prop_id"; $result = $dbh->getOne($sql); $res['conditional'] = (is_numeric($result)) ? $result : 0; return $res; @@ -1083,7 +1083,7 @@ function getCount($dbh, $proposalId) { $sql = "SELECT COUNT(user_handle) FROM package_proposal_votes WHERE - pkg_prop_id = ".$proposalId." GROUP BY pkg_prop_id"; + pkg_prop_id = ".$proposalId." GROUP BY pkg_prop_id"; $res = $dbh->getOne($sql); return (!empty($res)) ? $res: " 0"; } Index: scripts/rev.php =================================================================== RCS file: /repository/docweb/scripts/rev.php,v retrieving revision 1.17 diff -u -r1.17 rev.php --- scripts/rev.php 12 Aug 2006 16:14:13 -0000 1.17 +++ scripts/rev.php 4 Dec 2006 23:06:58 -0000 @@ -26,7 +26,7 @@ error_reporting(E_ALL); /** -* Usage +* Usage **/ // keep this call, we need it @@ -55,7 +55,7 @@ } /** -* Configuration +* Configuration **/ // define some common variables @@ -157,7 +157,7 @@ SQL; /** -* Functions +* Functions **/ function parse_translation($lang) @@ -476,7 +476,7 @@ } /** -* Script execution +* Script execution **/ $time_start = getmicrotime(); Index: templates/all/www/users.tpl.php =================================================================== RCS file: /repository/docweb/templates/all/www/users.tpl.php,v retrieving revision 1.8 diff -u -r1.8 users.tpl.php --- templates/all/www/users.tpl.php 1 Aug 2005 18:12:35 -0000 1.8 +++ templates/all/www/users.tpl.php 4 Dec 2006 23:06:58 -0000 @@ -72,10 +72,10 @@ HTML; if ($info['wishlist']) - echo "&docweb.users.wishlist;
"; + echo "&docweb.users.wishlist;
"; if (is_file($_SERVER['DOCUMENT_ROOT'] . '/images/users/' . $info['username'] . '.jpg')) - echo "&docweb.users.photo;"; + echo "&docweb.users.photo;"; echo '

'; Index: templates/all/www/shared/header.tpl.php =================================================================== RCS file: /repository/docweb/templates/all/www/shared/header.tpl.php,v retrieving revision 1.7 diff -u -r1.7 header.tpl.php --- templates/all/www/shared/header.tpl.php 2 Aug 2005 13:29:43 -0000 1.7 +++ templates/all/www/shared/header.tpl.php 4 Dec 2006 23:06:58 -0000 @@ -44,7 +44,7 @@
&docweb.common.header.project-doc-bugs;
-
&docweb.common.header.open-bugs;
+
&docweb.common.header.open-bugs;
Index: www/admin.php =================================================================== RCS file: /repository/docweb/www/admin.php,v retrieving revision 1.7 diff -u -r1.7 admin.php --- www/admin.php 5 Sep 2006 22:50:30 -0000 1.7 +++ www/admin.php 4 Dec 2006 23:06:58 -0000 @@ -23,7 +23,7 @@ auth(); if (!is_admin()) { - die('you are not an admin!'); + die('you are not an admin!'); } ob_start(); // hack for phpinfo() @@ -33,9 +33,9 @@ // helper functions function info() { - ob_end_clean(); //get ride of the headers - phpinfo(); - exit; + ob_end_clean(); //get ride of the headers + phpinfo(); + exit; } function pearinfo() { @@ -48,62 +48,62 @@ function print_file_list($base) { - if (!empty($_GET['file']) && !is_dir(dirname(__FILE__) . "/../$_GET[file]")) - return; + if (!empty($_GET['file']) && !is_dir(dirname(__FILE__) . "/../$_GET[file]")) + return; - $files = glob(dirname(__FILE__) . '/../' . @$_GET['file'] . $base); - $uri = preg_replace('/&file=[^&]*/', '', $_SERVER['REQUEST_URI']); - if ($files) { - echo '

Available files:

    '; - foreach ($files as $file) { - $file = basename($file); - if ($file == 'CVS') continue; - echo "
  • $file
  • "; - } - echo '
'; - } else { - echo '

There are no files currently available

'; - } + $files = glob(dirname(__FILE__) . '/../' . @$_GET['file'] . $base); + $uri = preg_replace('/&file=[^&]*/', '', $_SERVER['REQUEST_URI']); + if ($files) { + echo '

Available files:

    '; + foreach ($files as $file) { + $file = basename($file); + if ($file == 'CVS') continue; + echo "
  • $file
  • "; + } + echo '
'; + } else { + echo '

There are no files currently available

'; + } } function sql() { - if (empty($_POST['command'])) { - sql_print_textarea('', @$_REQUEST['file']); + if (empty($_POST['command'])) { + sql_print_textarea('', @$_REQUEST['file']); - // execute the sql - } else { - $file = dirname(__FILE__) . '/../sqlite/' . $_POST['file']; - $idx = sqlite_open($file, 0666, $error); - if (!$idx) { - echo "

$error

"; - sql_print_textarea($_POST['command'], $_POST['file']); - return; - } - - $result = sqlite_query($idx, $_POST['command']); - - if (!$result) { - echo '

There was an error in the query: ' . sqlite_error_string(sqlite_last_error($idx)) . '

 

'; - sql_print_textarea($_POST['command'], $_POST['file']); - return; - } - - echo '

File size: ' . filesize($file) / 1024 . ' KB

'; - echo '

Affected rows: ' . sqlite_changes($idx) , '

'; - echo '
' . htmlspecialchars(print_r(sqlite_fetch_all($result), true)) . '
'; - sqlite_close($idx); - sql_print_textarea($_POST['command'], $_POST['file']); - } + // execute the sql + } else { + $file = dirname(__FILE__) . '/../sqlite/' . $_POST['file']; + $idx = sqlite_open($file, 0666, $error); + if (!$idx) { + echo "

$error

"; + sql_print_textarea($_POST['command'], $_POST['file']); + return; + } + + $result = sqlite_query($idx, $_POST['command']); + + if (!$result) { + echo '

There was an error in the query: ' . sqlite_error_string(sqlite_last_error($idx)) . '

 

'; + sql_print_textarea($_POST['command'], $_POST['file']); + return; + } + + echo '

File size: ' . filesize($file) / 1024 . ' KB

'; + echo '

Affected rows: ' . sqlite_changes($idx) , '

'; + echo '
' . htmlspecialchars(print_r(sqlite_fetch_all($result), true)) . '
'; + sqlite_close($idx); + sql_print_textarea($_POST['command'], $_POST['file']); + } } function sql_print_textarea($txt, $file) { - print_file_list('sqlite/*.sqlite'); + print_file_list('sqlite/*.sqlite'); - echo <<< HTML + echo <<< HTML

 

SQL:

@@ -117,64 +117,64 @@ function chmodf() { - if (empty($_POST['mod']) || empty($_REQUEST['file'])) { - rmch_print_html(@$_REQUEST['file'], @$_POST['mod'], true); + if (empty($_POST['mod']) || empty($_REQUEST['file'])) { + rmch_print_html(@$_REQUEST['file'], @$_POST['mod'], true); - // change the permissions - } else { - $path = realpath(dirname(__FILE__) . "/../$_POST[file]"); - $allowed = dirname(dirname(__FILE__)); - - if (strncmp($path, $allowed, strlen($allowed))) { - echo "

The file isn't within an allowed directory!

"; - return; - } - - if (chmod($path, octdec($_POST['mod']))) - echo '

chmod() ok!

'; - else - echo '

chmod() failed!

'; - } + // change the permissions + } else { + $path = realpath(dirname(__FILE__) . "/../$_POST[file]"); + $allowed = dirname(dirname(__FILE__)); + + if (strncmp($path, $allowed, strlen($allowed))) { + echo "

The file isn't within an allowed directory!

"; + return; + } + + if (chmod($path, octdec($_POST['mod']))) + echo '

chmod() ok!

'; + else + echo '

chmod() failed!

'; + } } function rm() { - if (empty($_REQUEST['file'])) { - rmch_print_html(@$_REQUEST['file'], '', false); + if (empty($_REQUEST['file'])) { + rmch_print_html(@$_REQUEST['file'], '', false); - // change the permissions - } else { - $path = realpath(dirname(__FILE__) . "/../$_REQUEST[file]"); - $allowed = dirname(dirname(__FILE__)); - - if (strncmp($path, $allowed, strlen($allowed))) { - echo "

The file isn't within an allowed directory!

"; - return; - } - - if (unlink($path)) - echo '

unlink() ok!

'; - else - echo '

unlink() failed!

'; - } + // change the permissions + } else { + $path = realpath(dirname(__FILE__) . "/../$_REQUEST[file]"); + $allowed = dirname(dirname(__FILE__)); + + if (strncmp($path, $allowed, strlen($allowed))) { + echo "

The file isn't within an allowed directory!

"; + return; + } + + if (unlink($path)) + echo '

unlink() ok!

'; + else + echo '

unlink() failed!

'; + } } function rmch_print_html($file, $val, $mod) { - print_file_list('/*'); + print_file_list('/*'); - echo <<< HTML + echo <<< HTML

 

File:

HTML; - if ($mod) - echo '

Permissions:

'; + if ($mod) + echo '

Permissions:

'; - echo <<< HTML + echo <<< HTML

HTML; @@ -186,7 +186,7 @@ if (empty($_GET['z'])) { $lastCVSUpdate = date ('r', filemtime('./CVS/Entries')); - echo <<< HTML + echo <<< HTML

Menu:

  • SQL Injector
  • @@ -200,18 +200,18 @@ HTML; } else { - switch ($_GET['z']) { - case 'sql': - case 'chmodf': - case 'rm': - case 'info': - case 'pearinfo': - $_GET['z'](); - break; - - default: - echo '

    wrong zone!

    '; - } + switch ($_GET['z']) { + case 'sql': + case 'chmodf': + case 'rm': + case 'info': + case 'pearinfo': + $_GET['z'](); + break; + + default: + echo '

    wrong zone!

    '; + } } Index: www/login.php =================================================================== RCS file: /repository/docweb/www/login.php,v retrieving revision 1.1 diff -u -r1.1 login.php --- www/login.php 10 Aug 2006 18:21:28 -0000 1.1 +++ www/login.php 4 Dec 2006 23:06:58 -0000 @@ -4,17 +4,17 @@ include '../include/init.inc.php'; if (isset($_COOKIE['MAGIC_COOKIE']) || !empty($_POST)) { - require_once '../include/lib_auth.inc.php'; - auth(); + require_once '../include/lib_auth.inc.php'; + auth(); if (isset($_REQUEST['return']) && !empty($_REQUEST['return'])) { header('Location: http://'.$_SERVER['HTTP_HOST'].$_REQUEST['return']); } - echo 'You are logged in'; - echo is_admin() ? ' with admin rights.' : '.'; + echo 'You are logged in'; + echo is_admin() ? ' with admin rights.' : '.'; } else { - echo site_header('docweb.common.header.login'); - echo DocWeb_Template::get('login.tpl.php'); - echo site_footer(); + echo site_header('docweb.common.header.login'); + echo DocWeb_Template::get('login.tpl.php'); + echo site_footer(); } ?> Index: www/notes_stats.php =================================================================== RCS file: /repository/docweb/www/notes_stats.php,v retrieving revision 1.7 diff -u -r1.7 notes_stats.php --- www/notes_stats.php 1 Aug 2005 12:40:32 -0000 1.7 +++ www/notes_stats.php 4 Dec 2006 23:06:58 -0000 @@ -54,8 +54,8 @@ echo site_header("docweb.common.header.notes-stats"); echo DocWeb_Template::get( 'notes_stats.tpl.php', - $notesData + $notesData ); echo site_footer(); -?> +?> Index: www/phpt_generator.php =================================================================== RCS file: /repository/docweb/www/phpt_generator.php,v retrieving revision 1.4 diff -u -r1.4 phpt_generator.php --- www/phpt_generator.php 3 Dec 2006 11:51:29 -0000 1.4 +++ www/phpt_generator.php 4 Dec 2006 23:06:58 -0000 @@ -92,7 +92,7 @@ auth(); if (!is_admin()) { - die('you are not an admin!'); + die('you are not an admin!'); } } Index: www/users.php =================================================================== RCS file: /repository/docweb/www/users.php,v retrieving revision 1.8 diff -u -r1.8 users.php --- www/users.php 11 Aug 2005 15:25:38 -0000 1.8 +++ www/users.php 4 Dec 2006 23:06:58 -0000 @@ -24,9 +24,9 @@ } if (!$info = user_info($userid)) { - $info[ 'name' ] = master_user_name($userid); - $info['username'] = $userid; - $info['country' ] = $info['site'] = $info['wishlist'] = ''; + $info[ 'name' ] = master_user_name($userid); + $info['username'] = $userid; + $info['country' ] = $info['site'] = $info['wishlist'] = ''; } if (isset($_POST['editSubmit'])) { Index: www/rfc/rfc-proposal-edit.php =================================================================== RCS file: /repository/docweb/www/rfc/rfc-proposal-edit.php,v retrieving revision 1.16 diff -u -r1.16 rfc-proposal-edit.php --- www/rfc/rfc-proposal-edit.php 1 Aug 2005 09:42:48 -0000 1.16 +++ www/rfc/rfc-proposal-edit.php 4 Dec 2006 23:06:59 -0000 @@ -242,7 +242,7 @@ case 'vote': default: if (is_admin() && - ($proposal->user_handle != $docwebUser)) { + ($proposal->user_handle != $docwebUser)) { $next_stage_text = 'Extend vote time'; } else { $next_stage_text = ''; @@ -333,7 +333,7 @@ } else { if (isset($proposal) && $proposal->status != 'draft') { if (!empty($values['action_comment']) || (is_admin() && - ($proposal->user_handle != $docwebUser))) { + ($proposal->user_handle != $docwebUser))) { if (empty($values['action_comment'])) { PEAR::raiseError('A changelog comment is required.'); } Index: www/rfc/rfc-votes-show.php =================================================================== RCS file: /repository/docweb/www/rfc/rfc-votes-show.php,v retrieving revision 1.11 diff -u -r1.11 rfc-votes-show.php --- www/rfc/rfc-votes-show.php 4 Aug 2005 07:53:07 -0000 1.11 +++ www/rfc/rfc-votes-show.php 4 Dec 2006 23:06:59 -0000 @@ -251,7 +251,7 @@ foreach ($proposal->votes as $vote) { if (!isset($users[$vote->user_handle])) { - $users[$vote->user_handle] = array('name'=>user_name($vote->user_handle)); + $users[$vote->user_handle] = array('name'=>user_name($vote->user_handle)); } if ($vote->value > 0) { $vote->value = '+' . $vote->value;