Hi guys,I noticed there was a bug in pie.php which occurs whenever a very small (load) percentage was drawn as a pie slice. When drawing these small pie slices, the entire background of the pie chart got floodfilled with color.
I have fixed the bug and while I was at it I added a 3D look/feel to the chart.
I have attached the following to this e-mail: - screenshot of the bugged pie chart - screenshot of my new pie chart - diff patch Let me know if you think this patch is okay. ;) Kind regards, - Ramon. -- ing. R. Bastiaans HPC - Systems Programmer SARA - Computing and Networking Services Kruislaan 415 PO Box 194613 1098 SJ Amsterdam 1090 GP Amsterdam Tel. +31 (0) 20 592 3000 Fax. +31 (0) 20 668 3167 --- There are really only three types of people: Those who make things happen, those who watch things happen and those who say, "What happened?"
--- /home/sara/hpc/ramon/src/ganglia_cvs/monitor-core/web/pie.php
2005-10-10 09:42:26.000000000 +0200
+++ ./pie.php 2006-03-09 17:42:14.189725869 +0100
@@ -112,6 +112,10 @@
** Initialize the object and draw the pie. This would be the
** constructor in an ordinary OO scenario -- just that we haven't
** got constructors in PHP, now do we? ;-)
+ **
+ ** RB 09.03.2006:
+ ** - rearranged: please use indentation to seperate if/for
blocks/statements!
+ ** - modified to use draw_slices in stead of draw_slice
*/
function init ($w, $h, $d) {
$this->im= ImageCreate($w, $h);
@@ -127,34 +131,24 @@
$this->fy = array(0, 7,8,10,14,11);
/* decide the diameter of the pie */
if ($this->da_height > $this->da_width) {
- $this->diameter = $this->da_width;
+ $this->diameter = $this->da_width;
} else {
- $this->diameter = $this->da_height;
+ $this->diameter = $this->da_height;
}
$this->white = ImageColorAllocate($this->im, 255, 255, 255);
$this->black = ImageColorAllocate($this->im,0,0,0);
$n = count($this->data);
for ($i = 0; $i < $n; $i++) {
- $this->colors[$i] = ImageColorAllocate($this->im, $this->data[$i][2],
- $this->data[$i][3],
- $this->data[$i][4]);
- $this->sum += $this->data[$i][0];
+ $this->colors[$i] = ImageColorAllocate($this->im, $this->data[$i][2],
+ $this->data[$i][3],
+ $this->data[$i][4]);
+ $this->sum += $this->data[$i][0];
}
$from = 0;$to = 0;
for ($i = 0; $i < $n; $i++) {
- $this->angles[$i] = $this->roundoff(($this->data[$i][0] * 360)
- / doubleval($this->sum));
- $to = $from + $this->angles[$i];
- $col = $this->colors[$i];
-
- $foo = $this->angles[$i];
- $this->draw_slice($this->center_x,
- $this->center_y,
- $from,
- $to,
- $this->colors[$i]);
- $from += $this->angles[$i];
+ $this->angles[$i] = $this->roundoff( ($this->data[$i][0] * 360) /
doubleval($this->sum));
}
+ $this->draw_slices( $this->center_x, $this->center_y, $this->angles,
$this->colors );
}
/* }}} */
/* {{{ set_legend_percent */
@@ -264,33 +258,66 @@
}
}
/* }}} */
- /* {{{ draw_slice */
+ /* {{{ draw_slices */
/*
- ** This function draws a piece of pie centered at x,y starting at
+ ** This function draws pieces of pie centered at x,y starting at
** "from" degrees and ending at "to" degrees using the specified color.
+ **
+ ** RB 09.03.2006:
+ ** - fixed: ImageFill for pie slices broke when a very small pie was
drawn,
+ ** and filled entire image with color (orange background color).
+ ** - modified draw_slice to be draw_slices and added 3D effect ;)
*/
- function draw_slice ($x, $y, $from, $to, $color) {
- # Awful Kludge!!!
- if ($to > 360) {
- $to = 360;
- }
- ImageArc($this->im, $this->center_x, $this->center_y,
- $this->diameter, $this->diameter, $from, $to, $color);
- /* First line */
- $axy2 = $this->get_xy_factors($from);
- $ax2 = floor($this->center_x + ($axy2[0] * ($this->diameter /2)));
- $ay2 = floor($this->center_y + ($axy2[1] * ($this->diameter /2)));
- ImageLine($this->im, $this->center_x, $this->center_y, $ax2, $ay2,
$color);
- /* Second line */
- $bxy2 = $this->get_xy_factors($to);
- $bx2 = ceil($this->center_x + ($bxy2[0] * ($this->diameter /2)));
- $by2 = ceil($this->center_y + ($bxy2[1] * ($this->diameter /2)));
- ImageLine($this->im, $this->center_x, $this->center_y, $bx2, $by2,
$color);
- /* decide where to start filling, then fill */
- $xy2 = $this->get_xy_factors((($to - $from) / 2) + $from);
- $x2 = floor($this->center_x + ($xy2[0] * ($this->diameter /3)));
- $y2 = floor($this->center_y + ($xy2[1] * ($this->diameter /3)));
- ImageFillToBorder($this->im, $x2, $y2, $color, $color);
+ function draw_slices( $x, $y, $angles, $colors ) {
+
+ $pie_count = count( $angles );
+ $PIE_THICKNESS = ($this->diameter * 0.075);
+
+ for( $j = ($this->center_y+$PIE_THICKNESS); $j > $this->center_y; $j-- )
{
+
+ $from = 0;
+
+ for( $p = 0; $p < $pie_count; $p++ ) {
+
+ $to = $from + $angles[$p];
+
+ if( $to > 360 )
+ $to = 360;
+
+ $color = $colors[$p];
+ $orig_colors = imageColorsForIndex( $this->im, $color );
+
+ $dark_red = ( $orig_colors['red'] > 30 ) ? $orig_colors['red'] - 30
: $orig_colors['red'];
+ $dark_green = ( $orig_colors['green'] > 30 ) ? $orig_colors['green']
- 30 : $orig_colors['green'];
+ $dark_blue = ( $orig_colors['blue'] > 30 ) ? $orig_colors['blue'] -
30 : $orig_colors['blue'];
+
+ $new_color = ImageColorAllocate( $this->im, $dark_red, $dark_green,
$dark_blue );
+
+ ImageFilledArc( $this->im, $this->center_x, $j, $this->diameter,
$this->diameter, $from, $to, $new_color, IMG_ARC_PIE );
+
+ $from += $angles[$p];
+ }
+ }
+
+ $from = 0;
+
+ for( $p = 0; $p < $pie_count; $p++ ) {
+
+ $to = $from + $angles[$p];
+
+ $color = $colors[$p];
+
+ if( $to > 360 )
+ $to = 360;
+
+ if ($to > 360) {
+ $to = 360;
+ }
+
+ ImageFilledArc( $this->im, $this->center_x, $this->center_y,
$this->diameter, $this->diameter, $from, $to, $color, IMG_ARC_PIE );
+
+ $from += $angles[$p];
+ }
}
/* }}} */
/* {{{ display */
<<inline: pienew.jpg>>
<<inline: piebug.jpg>>
