文字

imagefilledarc

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

imagefilledarc画一椭圆弧且填充

说明

bool imagefilledarc ( resource $image , int $cx , int $cy , int $width , int $height , int $start , int $end , int $color , int $style )

在指定的 image 上画一椭圆弧且填充。

参数

image

由图象创建函数(例如 imagecreatetruecolor() )返回的图象资源。

cx

中间的 x 坐标。

cy

中间的 y 坐标。

width

椭圆弧的宽度。

height

椭圆弧的高度。

start

起点角度。

end

终点角度。 0° is located at the three-o'clock position, and the arc is drawn clockwise.

color

imagecolorallocate() 创建的颜色标识符。

style

值可以是下列值的按位或(OR):

  1. IMG_ARC_PIE
  2. IMG_ARC_CHORD
  3. IMG_ARC_NOFILL
  4. IMG_ARC_EDGED
IMG_ARC_PIE IMG_ARC_CHORD 是互斥的; IMG_ARC_CHORD 只是用直线连接了起始和结束点, IMG_ARC_PIE 则产生圆形边界。 IMG_ARC_NOFILL 指明弧或弦只有轮廓,不填充。 IMG_ARC_EDGED 指明用直线将起始和结束点与中心点相连,和 IMG_ARC_NOFILL 一起使用是画饼状图轮廓的好方法(而不用填充)。

返回值

成功时返回 TRUE , 或者在失败时返回 FALSE

范例

Example #1 创建一 3D 效果的饼状图

<?php

// 创建图像
$image  imagecreatetruecolor ( 100 100 );

// 分配一些颜色
$white     imagecolorallocate ( $image 0xFF 0xFF 0xFF );
$gray      imagecolorallocate ( $image 0xC0 0xC0 0xC0 );
$darkgray  imagecolorallocate ( $image 0x90 0x90 0x90 );
$navy      imagecolorallocate ( $image 0x00 0x00 0x80 );
$darknavy  imagecolorallocate ( $image 0x00 0x00 0x50 );
$red       imagecolorallocate ( $image 0xFF 0x00 0x00 );
$darkred   imagecolorallocate ( $image 0x90 0x00 0x00 );

// 创建 3D 效果
for ( $i  60 $i  50 $i --) {
   
imagefilledarc ( $image 50 $i 100 50 0 45 $darknavy IMG_ARC_PIE );
   
imagefilledarc ( $image 50 $i 100 50 45 75  $darkgray IMG_ARC_PIE );
   
imagefilledarc ( $image 50 $i 100 50 75 360  $darkred IMG_ARC_PIE );
}

imagefilledarc ( $image 50 50 100 50 0 45 $navy IMG_ARC_PIE );
imagefilledarc ( $image 50 50 100 50 45 75  $gray IMG_ARC_PIE );
imagefilledarc ( $image 50 50 100 50 75 360  $red IMG_ARC_PIE );


// 输出图像
header ( 'Content-type: image/png' );
imagepng ( $image );
imagedestroy ( $image );
?>

以上例程的输出类似于:

例子输出:创建一 3D 效果的饼状图

注释

Note: 此函数需要 GD 2.0.1 或更高版本(推荐 2.0.28 及更高版本)。

用户评论:

[#1] xcoda3 at web dot de [2015-07-23 16:24:07]

For everyone who will use imageellipse() with a border (imagesetthickness() not working correctly).
This function simualtes the standard gd border.

<?php

function imageEllipseWithBorder($image$centerX$centerY$width$height$color$borderWidth)
    {
        
// Calculate inner and outer strength of border
        
$borderOuterStrength = (($borderWidth 1) / 2);
        
$borderInnerStrength = ((($borderWidth 1) / 2) + 1);

        
// Caculate x-/y-offset from 0/0 position to ellipse center
        
$ellipseXOffset $centerX - ($width 2) - $borderOuterStrength;
        
$ellipseYOffset $centerY - ($height 2) - $borderOuterStrength;

        
// Create temp image for editing
        
$tempImageWidth  $width + ($borderOuterStrength 2) + 1;
        
$tempImageHeight $height + ($borderInnerStrength 2) + 1;
        
$tempImage imagecreatetruecolor($tempImageWidth$tempImageHeight);
        
imagealphablending($tempImagefalse);

        
// Fill temp image with "transparent" color
        
$transparent imagecolorallocatealpha($tempImage255255255127);
        
imagefill($tempImage00$transparent);

        
// Draw outer ellipse (representing the border)
        
imagefilledellipse(
            
$tempImage,
            
$centerX $ellipseXOffset,
            
$centerY $ellipseYOffset,
            
$width  $borderOuterStrength 2,
            
$height $borderOuterStrength 2,
            
$color
        
);

        
// Draw inner ellipse (transparent area)
        
imagefilledellipse(
            
$tempImage,
            
$centerX $ellipseXOffset,
            
$centerY $ellipseYOffset,
            
$width $borderInnerStrength 2,
            
$height $borderInnerStrength 2,
            
$transparent
        
);

        
// "Paste" ellipse (with transparent inner area) into image at original position
        
imagealphablending($imagetrue);
        
imagecopy(
            
$image,
            
$tempImage,
            
$ellipseXOffset + ($borderWidth 1) % 2,
            
$ellipseYOffset + ($borderWidth 1) % 2,
            
0,
            
0,
            
$tempImageWidth,
            
$tempImageHeight
        
);
    }

?>

[#2] floripondia dot 88 at hotmail dot com [2013-11-22 16:28:29]

If you want to make a pie graph with exploded slices and data shows on each one and data side right too you can use this snippet.
<?php
$values 
= array("2010" => 1950"2011" => 750"2012" => 2100"2013" => 580"2014" => 5000);
$total count($values);
$data = ($total == 0) ? array(360) : array_values($values);
$keys = ($total == 0) ? array("") : array_keys($values);
$radius 30;
$imgx 1800 $radius;
$imgy 600 $radius;
$cx 400 $radius;
$cy 200 $radius;
$sx 800;
$sy 400;
$sz 150;
$data_sum array_sum($data);
$angle_sum = array(-=> 0360);
$typo "./helvetica.ttf";
$im imagecreate($imgx$imgy);
imagecolorallocate($im255255255);
$color = array(
    array(
2202060),
    array(
7733114),
    array(
24914153),
    array(
1583759),
    array(
1128128),
    array(
2894160),
    
//array(206, 16, 118),
    
array(436786),
    
//array(155, 108, 166),
    
array(836962)
);
shuffle($color);
shuffle($color);
shuffle($color);
$colors = array(imagecolorallocate($im$color[0][0], $color[0][1], $color[0][2]));
$colord = array(imagecolorallocate($im, ($color[0][0] / 1.5), ($color[0][1] / 1.5), ($color[0][2] / 1.5)));
$factorx = array();
$factory = array();
for(
$i 0$i $total$i++){
    
$angle[$i] = (($data[$i] / $data_sum) * 360);
    
$angle_sum[$i] = array_sum($angle);
    
$colors[$i] = imagecolorallocate($im$color[$i][0], $color[$i][1], $color[$i][2]);
    
$colord[$i] = imagecolorallocate($im, ($color[$i][0] / 1.5), ($color[$i][1] / 1.5), ($color[$i][2] / 1.5));
    
$factorx[$i] = cos(deg2rad(($angle_sum[$i 1] + $angle_sum[$i]) / 2));
    
$factory[$i] = sin(deg2rad(($angle_sum[$i 1] + $angle_sum[$i]) / 2));
}
for(
$z 1$z <= $sz$z++){
    for(
$i 0$i $total$i++){
        
imagefilledarc($im$cx + ($factorx[$i] * $radius), (($cy $sz) - $z) + ($factory[$i] * $radius), $sx$sy$angle_sum[$i 1], $angle_sum[$i], $colord[$i], IMG_ARC_PIE);
    }
}
for(
$i 0$i $total$i++){
    
imagefilledarc($im$cx + ($factorx[$i] * $radius), $cy + ($factory[$i] * $radius), $sx$sy$angle_sum[$i 1], $angle_sum[$i], $colors[$i], IMG_ARC_PIE);
    
imagefilledrectangle($im90050 + ($i 50 2), 950100 + ($i 50 2), $colors[$i]);
    
imagettftext($im500970100 + ($i 50 2), imagecolorallocate($im000), $typo$keys[$i]);
    
imagettftext($im400$cx + ($factorx[$i] * ($sx 4)) - 40$cy + ($factory[$i] * ($sy 4)) + 10imagecolorallocate($im000), $typo$data[$i]);
}
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

[#3] splogamurugan at gmail dot com [2011-02-09 02:53:25]

A simple pie chart generation script. 
Displays the percentage at center arc and displays the Legends with random colors. 

<?php
class simplepie
{
    function 
__construct($width$height$dataArr)
    {
        
$font './verdana.ttf'
        
$this->image imagecreate($width,$height);
        
$piewidth $width 0.70;
        
$x round($piewidth/2);
        
$y round($height/2);
        
$total array_sum($dataArr);
        
$angle_start 0;
        
$ylegend 2;
        
imagefilledrectangle($this->image00$width$piewidthimagecolorallocate($this->image128128128));
        foreach(
$dataArr as $label=>$value) {
            
$angle_done    = ($value/$total) * 360
            
$perc          round(($value/$total) * 1001); 
            
$color         imagecolorallocate($this->imagerand(0255), rand(0255), rand(0255));
            
imagefilledarc($this->image$x$y$piewidth$height$angle_start$angle_done+= $angle_start$colorIMG_ARC_PIE);
            
$xtext $x + (cos(deg2rad(($angle_start+$angle_done)/2))*($piewidth/4));
            
$ytext $y + (sin(deg2rad(($angle_start+$angle_done)/2))*($height/4)); 
            
imagettftext($this->image60$xtext$ytextimagecolorallocate($this->image000), $font"$perc %");
            
imagefilledrectangle($this->image$piewidth+2$ylegend$piewidth+20$ylegend+=20$color); 
            
imagettftext($this->image80$piewidth+22$ylegendimagecolorallocate($this->image000), $font$label);
            
$ylegend += 4;
            
$angle_start $angle_done;
        }
    }
    function 
render()
    {
        
header('Content-type: image/png');
        
imagepng($this->image);
    }
}

$dataArr = array(2001=>102002=>302003=>502004=>10);
$width=600;
$height=480;
$pie = new simplepie($width$height$dataArr);
$pie->render();
?>

[#4] Christopher Kramer [2009-09-17 04:25:22]

If this function is not available because you're using an old gdlib version, here is a workaround if you want to draw a pie chart:

<?php

// width and height of the image
$width=200;
$height=200;

$simulate_old_gd=true// do not use imagefilledarc although available? 

// the pieces of the pie (in degree)
$pieces=array(180,90,45,25,15,5);

$diagram=imagecreate($width,$height);

// background color
$white=imagecolorallocate($diagram255255255);
imagefilledrectangle($diagram,0,0,$width,$height,$white);

// the circle is 2px smaller than the image
$width-=2;
$height-=2;

// we need a border color
$black=imagecolorallocate($diagram000);

// draw the border of the pie
imagearc($diagramround($width/2), round($height/2), 
         
$width$height0360$black);

// position (in degrees) where to place the next piece
$position=270
// we will use calculated gray colors for simple example
$gray=0

foreach(
$pieces as $deg)
 {
 
// calculate the gray color
 
$gray+=30;
 if(
$gray>255$gray=0;
 
$color=imagecolorallocate($diagram,$gray,$gray,$gray);
 
 
// position must be kept < 360
 
if($position>360$position-=360;

 if(!
$simulate_old_gd && is_callable('imagefilledarc'))
  {  
  
imagefilledarc($diagramround($width/2), 
  
round($height/2), $width$height$position
  
$position+$deg$color,IMG_ARC_EDGED);
  }
 else
  {
  
// we use some maths to calculate the pixel on the circle
  
$pix_x=round(floor(($width-2)/2)*cos($position/180*M_PI)
         +
round($width/2));
  
$pix_y=round(floor(($height-2)/2)*sin($position/180*M_PI)
         +
round($height/2));
  
// now we  draw a line from the mid of the circle to the
  // calculated pixel on the circle
  
imageline($diagramround($width/2), round($height/2), 
            
$pix_x$pix_y$black);
  
// now we need a pixel for flood filling.
  //- We could use maths to calculate a pixel inside the 
  // piece:
  //$fill_x=round(floor(($width-10)/2)*
  //        cos(($position+2)/180*M_PI)+round($width/2));
  //$fill_y=round(floor(($height-10)/2)*
  //        sin(($position+2)/180*M_PI)+round($height/2));
  //- or we could use an universal pixel with less maths ;)  
  // (top mid):
  
$fill_x=floor($width/2)-2;
  
$fill_y=3;
  
// now we flood fill the circle
  
@imagefilltoborder ($diagram,$fill_x,$fill_y,$black,$color);
  

  
}
 
// the position of the next piece is $deg degrees further
 
$position+=$deg;
 }
 
// output the image
header('Content-type: image/png');
imagepng($diagram);
imagedestroy($digram);
?>

[#5] mateusz dot charytoniuk at gmail dot com [2009-02-26 09:31:00]

The code below uses colors from "hans at lintoo dot dk"'s note. It delivers pie charts with labels:

<?php
$bright_list 
= array(
    array(
2552033),
    array(
22010129),
    array(
1892451),
    array(
2140127),
    array(
98196),
    array(
062136),
    array(
0102179),
    array(
0145195),
    array(
0115106),
    array(
17821052),
    array(
1379174),
    array(
825647)
);
$dark_list = array(
    array(
2051530),
    array(
170510),
    array(
13901),
    array(
164077),
    array(
48046),
    array(
01286),
    array(
052129),
    array(
095145),
    array(
06556),
    array(
1281602),
    array(
874124),
    array(
3260)
);

$data = array();
$angle = array();
$title = array();
$i 0;
foreach( 
$_GET as $key => $value ) {
    
$data[$i] = intval($value);
    
$title[$i++] = str_replace("_"," ",strval($key));
}
$sum array_sum($data);
if( 
$sum == ) {
    ++ 
$sum;
}
$count count($data);
for( 
$i 0$i $count; ++ $i ) {
    
$angle[$i] = floor($data[$i]/$sum*360);
    if( 
$angle[$i] == ) {
        ++ 
$angle[$i];
    }
}
$sum_angle array_sum($angle);
if( 
$sum_angle 360 ) {
    
$angle[0]+=360-$sum_angle;
}

$height $count*34;
if( 
$height 180 ) {
    
$height 180;
}

$im  imagecreate (350$height);
$background imagecolorallocate($im226226226);
$border imagecolorallocate($im,97,97,97);
$font_color imagecolorallocate($im,0,0,0);
$font 'yourfont.ttf';

$bright = array();
foreach( 
$bright_list as $c ) {
    
$bright[] = imagecolorallocate($im,$c[0],$c[1],$c[2]);
}

$dark = array();
foreach( 
$dark_list as $c ) {
    
$dark[] = imagecolorallocate($im,$c[0],$c[1],$c[2]);
}
$tmp 0;
for( 
$i =0$i $count; ++ $i ) {
    for( 
$j 100$j 90; -- $j ) {
        
imagefilledarc($im100$j180120$tmp$tmp+$angle[$i], $dark[$i], IMG_ARC_PIE);
    }
    
$tmp += $angle[$i];
}

$tmp 0;
for( 
$i =0$i $count; ++ $i ) {
    
imagefilledarc($im10090180120$tmp$tmp+$angle[$i], $bright[$i], IMG_ARC_PIE);
    
$tmp += $angle[$i];
}
for( 
$i 0$i $count; ++ $i ) {
    
imagefilledrectangle($im20919+($i*30), 23141+($i*30), $border);
    
imagefilledrectangle($im21020+($i*30), 23040+($i*30), $bright[$i]);
    
imagefttext($im11024034+($i*30), $font_color$font$title[$i]);
}
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>


try 'pie.php?foo=3&bar=4&baz=6'

[#6] Mike [2007-08-14 12:43:30]

The previous example does not work well.  This is much better and faster:

<?php
$Randomized 
rand(1,20);
for(
$i=0;$i<=$Randomized;$i++){$data[$i]=rand(2,20);};//full array with garbage.
$imgx='600';$imgy='400';//Set Image Size. ImageX,ImageY
$cx '300';$cy ='150'//Set Pie Postition. CenterX,CenterY
$sx '600';$sy='300';$sz ='100';// Set Size-dimensions. SizeX,SizeY,SizeZ

$data_sum array_sum($data);
//convert to angles.
for($i=0;$i<=$Randomized;$i++){
   
$angle[$i] = (($data[$i] / $data_sum) * 360);
   
$angle_sum[$i] = array_sum($angle);
};
$im  imagecreate ($imgx,$imgy);
$background imagecolorallocate($im255255255);
//Random colors.
for($i=0;$i<=$Randomized;$i++){
   
$r=rand(100,255);$g=rand(100,255);$b=rand(100,255);   
   
$colors[$i] = imagecolorallocate($im,$r,$g,$b);
   
$colord[$i] = imagecolorallocate($im,($r/1.5),($g/1.5),($b/1.5));
}
//3D effect.
for($z=1;$z<=$sz;$z++){
        
// first slice
    
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,0
    
,$angle_sum[0],$colord[0],IMG_ARC_EDGED);
   for(
$i=1;$i<=$Randomized;$i++){
        
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,$angle_sum[$i-1]
        ,
$angle_sum[$i],$colord[$i],IMG_ARC_NOFILL);
   };
};
//Top pie.
   // first slice
   
imagefilledarc($im,$cx,$cy,$sx,$sy,,$angle_sum[0], $colors[0], IMG_ARC_PIE);
for(
$i=1;$i<=$Randomized;$i++){
   
imagefilledarc($im,$cx,$cy,$sx,$sy,$angle_sum[$i-1] ,$angle_sum[$i], $colors[$i], IMG_ARC_PIE);
};
//Output.
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

[#7] imazir at gmail dot com [2006-01-31 02:53:03]

The previous example does not work. Try those modifications and you will have the expected results :

<?php
$Randomized 
rand(1,20);
for(
$i=0;$i<=$Randomized;$i++){$data[$i]=rand(2,20);};//full array with garbage.
$imgx='200';$imgy='200';//Set Image Size. ImageX,ImageY
$cx '100';$cy ='50'//Set Pie Postition. CenterX,CenterY
$sx '200';$sy='100';$sz ='20';// Set Size-dimensions. SizeX,SizeY,SizeZ

$data_sum array_sum($data);
//convert to angles.
for($i=0;$i<=$Randomized;$i++){
   
$angle[$i] = (($data[$i] / $data_sum) * 360);
   
$angle_sum[$i] = array_sum($angle);
};
$im  imagecreate ($imgx,$imgy);
$background imagecolorallocate($im255255255);
//Random colors.
for($i=0;$i<=$Randomized;$i++){
   
$r=rand(100,255);$g=rand(100,255);$b=rand(100,255);    
   
$colors[$i] = imagecolorallocate($im,$r,$g,$b);
   
$colord[$i] = imagecolorallocate($im,($r/2),($g/2),($b/2));
}
//3D effect.
for($z=1;$z<=$sz;$z++){
   for(
$i=1;$i<=$Randomized;$i++){
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,$angle_sum[$i-1]
,
$angle_sum[$i],$colord[$i],IMG_ARC_PIE);
   };
};
//Top pie.
for($i=1;$i<=$Randomized;$i++){
   
imagefilledarc($im,$cx,$cy,$sx,$sy,$angle_sum[$i-1] ,$angle_sum[$i], $colors[$i], IMG_ARC_PIE);
};
//Output.
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

[#8] paulcharltonthomson at hotmail dot com [2005-07-01 23:00:55]

Here's a slightly better way to get the colours for the pie chart shaded wall as posted by double-zonk at wp dot pl

<?php

$rgb0 
= array (255153204); 
$rgb1 = array (2551530); 
$rgb2 = array (1532040); 
$rgb3 = array (51153102); 
$rgb4 = array (51204204); 
$rgb5 = array (51102255); 
$rgb6 = array (1280128); 
$rgb7 = array (150150150); 

for (
$r 0$r 8; ++$r)
    { 
        if(${
"rgb" $r}[0] < 50$shadowr 0; else $shadowr = ${"rgb" $r}[0] - 50
        if(${
"rgb" $r}[1] < 50$shadowg 0; else $shadowg = ${"rgb" $r}[1] - 50
        if(${
"rgb" $r}[2] < 50$shadowb 0; else $shadowb = ${"rgb" $r}[2] - 50
        ${
"wall" $r} = array ($shadowr$shadowg$shadowb); 
    } 

for (
$s 0$s 8; ++$s)
    { 
        
$kolor[$s] = imagecolorallocate($image, ${"rgb" $s}[0], ${"rgb" $s}[1], ${"rgb" $s}[2]); 
        
$cien[$s] = imagecolorallocate($image, ${"wall" $s}[0], ${"wall" $s}[1], ${"wall" $s}[2]); 
    } 

?>

[#9] t_therkelsen at hotmail dot com [2005-03-08 01:21:52]

Note that imageFilledArc() and imageArc() both take ints as degree measurements.  This is no problem if you're *only* using imageArc() and/or imageFilledArc().  However, if you're using calculated degrees and plan to superimpose other drawing elements (eg., you want to make vertical lines between the shadow 3D effect) you need to floor() your degrees before converting them to radians, otherwise you'll get precision errors.

A small example illustrating the 'feature'...

<?php
$img 
imageCreate(400400);
$back imageColorAllocate($img000);
$front imageColorAllocate($img255255255);

$sd 45.5;
$ed 130.5;

imageFilledArc($img200200300300$sd$ed,
               
$frontIMG_ARC_PIE|IMG_ARC_NOFILL|IMG_ARC_EDGED);
imageArc($img200230300300$sd$ed$front);

imageLine($img,
          
cos(deg2rad($sd))*150+200sin(deg2rad($sd))*150+200,
          
cos(deg2rad($sd))*150+200sin(deg2rad($sd))*150+230,
          
$front);
imageLine($img,
          
cos(deg2rad($ed))*150+200sin(deg2rad($ed))*150+200,
          
cos(deg2rad($ed))*150+200sin(deg2rad($ed))*150+230,
          
$front);

header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
?>


And this is how it should be...

<?php
$img 
imageCreate(400400);
$back imageColorAllocate($img000);
$front imageColorAllocate($img255255255);

$sd floor(45.5);
$ed floor(130.5);

imageFilledArc($img200200300300$sd$ed,
               
$frontIMG_ARC_PIE|IMG_ARC_NOFILL|IMG_ARC_EDGED);
imageArc($img200230300300$sd$ed$front);

imageLine($img,
          
cos(deg2rad($sd))*150+200sin(deg2rad($sd))*150+200,
          
cos(deg2rad($sd))*150+200sin(deg2rad($sd))*150+230,
          
$front);
imageLine($img,
          
cos(deg2rad($ed))*150+200sin(deg2rad($ed))*150+200,
          
cos(deg2rad($ed))*150+200sin(deg2rad($ed))*150+230,
          
$front);

header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
?>

[#10] rich at dicksonlife dot com [2004-09-24 07:22:01]

Even more efficiency:

The original code snippet and the following suggestions are inefficient in that they rely on the overlying php to fill vertically using loops rather than taking advantage of the underlying drawing routines. Also, this is done by repeatedly drawing filled partial elipses and circular calculations are typically expensive (PHP may use tables, I'm not sure) The original code could be rewritten as 

<?php
// Add the bottom layer.
  
imagefilledarc($image506010050045$darknavyIMG_ARC_PIE);
  
imagefilledarc($image5060100504575 $darkgrayIMG_ARC_PIE);
  
imagefilledarc($image50601005075360 $darkredIMG_ARC_PIE);

//Now do the joining pieces.
//Note: Precompute cosines and sines for efficiency
  
$c1=50*cos(45/180*M_PI);
  
$s1=25*sin(45/180*M_PI);
  
$c2=50*cos(75/180*M_PI);
  
$s2=25*sin(75/180*M_PI);

  
$area1=array(100,60,100,50,50+$c1,50+$s1,50+$c1,60+$s1);
  
$area2=array(50+$c1,50+$s1,50+$c1,60+$s1,50+$c2,60+$s2,50+$c2,50+$s2);
//Note that piece 3 goes round the corner. So we are only interested in the leftmost extent. You would need to do this programatically. Also, you do not need to make vertical parts for any segments completely at the back of the pie (in fact, not filledarcs either)
  
$area3=array(50+$c2,50+$s2,50+$c2,60+$s2,0,60,0,50);

  
imagefilledpolygon($image$area1 $darknavy);
  
imagefilledpolygon($image$area2 $darkgray);
  
imagefilledpolygon($image$area3 $darkred);

  
imagefilledarc($image505010050045$navyIMG_ARC_PIE);
  
imagefilledarc($image5050100504575 $grayIMG_ARC_PIE);
  
imagefilledarc($image50501005075360 $redIMG_ARC_PIE);
?>


Note that the polygons are perhaps slightly inefficient. If there was an imagefilledtriangle, this code would be simpler. Given how fundamental triangles are, perhaps for a future version?

Rich

[#11] micha _a.t_ psytrance _d.o.t_ info [2004-09-08 19:09:05]

for nice colors and adapted shadows from amount of values i try:

<?php
function _errechne_gradzahlen$werte ) {             
    
foreach( $werte as $wert ) { $sum += $wert; }
    foreach( 
$werte as $wert ) { $gradzahlen[] = 360 * ( $wert $sum ); }
    return 
$gradzahlen;
}

function 
_randomcol $im ) {
    return 
imagecolorallocate$imrand(100224), rand(100224), rand(128224) );        
}

$values = array( 100200501004332 );    
$werte _errechne_gradzahlen$values );        
$width 200;
$height 200;
$half_width floor$width );
$half_height floor($height 2);

$im ImageCreateTrueColor$width$height );

foreach( 
$werte as $key => $wert ) {
    

    
$color _randomcol$im );                 
    
$shadow $color 20000;                 // or brighter shadows take 10000
    
$colors[] = $color;
    
$shadows[] = $shadow;

     
for ($i = ($half_height 10); $i $half_height$i--) {
        
imagefilledarc
                    
$im
                    
$half_width,  $i,         
                    
$width$half_height,
                    
$offset, ($offset $wert),   // from, to (degrees)
                    
$shadows[$key], IMG_ARC_NOFILL);
    }
    
$offset $offset $wert;
}
$offset 0;

foreach( 
$werte as $key => $wert ) {             
    
imagefilledarc
                
$im
                
$half_width$half_width
                
$width$half_height,           // half sized
                
$offset, ($offset $wert), 
                
$colors[$key], IMG_ARC_PIE);
    
$offset $offset $wert;
}
header"Content-type: image/png" );
imagepng $im );
imagedestroy$im );
?>


sry for my crab english and the disordered code, i cut and 'translate' it from a class i wrote before.

[#12] poopie [2004-08-05 21:08:32]

The examples given so far for drawing a 3D looking pie chart are extremely inefficient and can give a huge performance hit to scripts that draw a lot of pies and in particular those that do offline processing on disk, rather than send a single pie chart to the browser (either way this modification saves you a lot of CPU cycles).

Modify the portion of the code that creates the 3D effect to only draw the outline (with IMG_ARC_NOFILL) of the pie layers below the top filled pie:

// make the 3D effect (modified for the original example)
for ($i = 60; $i >= 50; $i--) {
   imagefilledarc($image, 50, $i, 100, 50, 0, 45, $darknavy, IMG_ARC_NOFILL);
  imagefilledarc($image, 50, $i, 100, 50, 45, 75 , $darkgray, IMG_ARC_NOFILL);
  imagefilledarc($image, 50, $i, 100, 50, 75, 360 , $darkred, IMG_ARC_NOFILL);
}

Note the >= on the for loop, which fills in a gap that is created without the =

[#13] hans at lintoo dot dk [2004-07-17 12:14:18]

I found some bugs in my script.. and therefore I am posting the fixes:
Bugs:
<?php
$drakcolor
[2] = imagecolorallocate($im13901);
//Should be
$darkcolor[2] = imagecolorallocate($im13901);
?>


And then if you modify the code a little and, then make a image 200x125 then you won't be wasting space.
Changes:
<?php
$im  
imagecreate (200125);
// AND
for ($i 60$i 50$i--) {
    
imagefilledarc($im100$i200100$anglesum[$f], $anglesum[$n], $darkcolor[$f], IMG_ARC_PIE);
}
// AND
       
imagefilledarc($im10050200100$anglesum[$n], $anglesum[$i], $randcolor[$n], IMG_ARC_PIE);
?>

you can see a online demo at: http://webstatistik.lintoo.dk/

[#14] hans at lintoo dot dk [2004-07-16 15:27:10]

I modificed the code to make a 3d pie from data collected elsewhere.... in this case it was for a statistics page...

when testing you can use:

enjoy

<?php
//Making a image 200 x 200
$im  imagecreate (200200);

//Setting background color
$background imagecolorallocate($im226226226);

//Setting colors of elements
$randcolor[0] = imagecolorallocate($im2552033);
$randcolor[1] = imagecolorallocate($im22010129);
$randcolor[2] = imagecolorallocate($im1892451);
$randcolor[3] = imagecolorallocate($im2140127);
$randcolor[4] = imagecolorallocate($im98196);
$randcolor[5] = imagecolorallocate($im062136);
$randcolor[6] = imagecolorallocate($im0102179);
$randcolor[7] = imagecolorallocate($im0145195);
$randcolor[8] = imagecolorallocate($im0115106);
$randcolor[9] = imagecolorallocate($im17821052);
$randcolor[10] = imagecolorallocate($im1379174);
$randcolor[11] = imagecolorallocate($im825647);

//Setting the darker alt color to the main color
$darkcolor[0] = imagecolorallocate($im2051530);
$darkcolor[1] = imagecolorallocate($im170510);
$drakcolor[2] = imagecolorallocate($im13901);
$darkcolor[3] = imagecolorallocate($im164077);
$darkcolor[4] = imagecolorallocate($im48046);
$darkcolor[5] = imagecolorallocate($im01286);
$darkcolor[6] = imagecolorallocate($im052129);
$darkcolor[7] = imagecolorallocate($im095145);
$darkcolor[8] = imagecolorallocate($im06556);
$darkcolor[9] = imagecolorallocate($im1281602);
$darkcolor[10] = imagecolorallocate($im874124);
$darkcolor[11] = imagecolorallocate($im3260);

//Getting the data from GET
$i 0;
while (
$i <= 11) {
$data[$i] = $_GET[++$i];
}

//Getting ready
$datasum array_sum($data);
$anglesum[0] = 0;
$angle[0] = 0;
$i 0;

//Calc the start and end angle position of the elements
while ($i <= 11) {
    ++
$i;
    
$n $i 1;
    
$part[$i] = $data[$n] / $datasum;
    
$angle[$i] = floor($part[$i] * 360);
    
$anglesum[$i] = array_sum($angle);
}



// make the 3D effect
$n 0;$i=0;
while (
$n <= 11) {
    ++
$n;
    
$f $n 1;
    if (
$angle[$n] != 0) {
        for (
$i 110$i 100$i--) {
            
imagefilledarc($im100$i200100$anglesum[$f], $anglesum[$n], $darkcolor[$f], IMG_ARC_PIE);
        }
    }
}

//make the 2d data that sits above the 3deffect
$i 0;
while (
$i <= 11) {
    ++
$i;
    
$n $i 1;
    if (
$angle[$i] != 0) {
       
imagefilledarc($im100100200100$anglesum[$n], $anglesum[$i], $randcolor[$n], IMG_ARC_PIE);
    }   
}

// flush image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

[#15] caist - www.caist.com [2004-01-07 08:11:07]

if you want to place a text onto the edge of a circle you need to
get a point on the circle:

$pos_x=$radius*sin(deg2rad($angle));
$pos_y=sqrt($radius*$radius-$pos_x*$pos_x);

if you want the point to be in the middle of a pie piece
you need a starting and ending angle

$pos_x=$radius*sin(deg2rad($angle_end-($angle_start)/2));
$pos_y=sqrt($radius*$radius-$pos_x*$pos_x);

hope it helps

上一篇: 下一篇: