⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpgraph_pie3d.php

📁 通达OA2007SE源代码 非常好的
💻 PHP
📖 第 1 页 / 共 2 页
字号:
<?php/*=======================================================================// File:	JPGRAPH_PIE3D.PHP// Description: 3D Pie plot extension for JpGraph// Created: 	2001-03-24// Author:	Johan Persson (johanp@aditus.nu)// Ver:		$Id: jpgraph_pie3d.php 571 2006-03-04 10:28:00Z ljp $//// Copyright (c) Aditus Consulting. All rights reserved.//========================================================================*///===================================================// CLASS PiePlot3D// Description: Plots a 3D pie with a specified projection // angle between 20 and 70 degrees.//===================================================class PiePlot3D extends PiePlot {    private $labelhintcolor="red",$showlabelhint=true;    private $angle=50;	    private $edgecolor="", $edgeweight=1;    private $iThickness=false;	//---------------// CONSTRUCTOR    function PiePlot3d($data) {	$this->radius = 0.5;	$this->data = $data;	$this->title = new Text("");	$this->title->SetFont(FF_FONT1,FS_BOLD);	$this->value = new DisplayValue();	$this->value->Show();	$this->value->SetFormat('%.0f%%');    }//---------------// PUBLIC METHODS		    // Set label arrays    function SetLegends($aLegend) {	$this->legends = array_reverse(array_slice($aLegend,0,count($this->data)));    }    function SetSliceColors($aColors) {	$this->setslicecolors = $aColors;    }    function Legend($aGraph) {	parent::Legend($aGraph);	$aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol);    }    function SetCSIMTargets($targets,$alts=null) {	$this->csimtargets = $targets;	$this->csimalts = $alts;    }    // Should the slices be separated by a line? If color is specified as "" no line    // will be used to separate pie slices.    function SetEdge($aColor='black',$aWeight=1) {	$this->edgecolor = $aColor;	$this->edgeweight = $aWeight;    }    // Dummy function to make Pie3D behave in a similair way to 2D    function ShowBorder($exterior=true,$interior=true) {	JpGraphError::RaiseL(14001);//('Pie3D::ShowBorder() . Deprecated function. Use Pie3D::SetEdge() to control the edges around slices.');    }    // Specify projection angle for 3D in degrees    // Must be between 20 and 70 degrees    function SetAngle($a) {	if( $a<5 || $a>90 )	    JpGraphError::RaiseL(14002);//("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees.");	else	    $this->angle = $a;    }    function Add3DSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) {  //Slice number, ellipse centre (x,y), height, width, start angle, end angle	$sa *= M_PI/180;	$ea *= M_PI/180;	//add coordinates of the centre to the map	$coords = "$xc, $yc";	//add coordinates of the first point on the arc to the map	$xp = floor($width*cos($sa)/2+$xc);	$yp = floor($yc-$height*sin($sa)/2);	$coords.= ", $xp, $yp";	//If on the front half, add the thickness offset	if ($sa >= M_PI && $sa <= 2*M_PI*1.01) {	    $yp = floor($yp+$thick);	    $coords.= ", $xp, $yp";	}			//add coordinates every 0.2 radians	$a=$sa+0.2;	while ($a<$ea) {	    $xp = floor($width*cos($a)/2+$xc);	    if ($a >= M_PI && $a <= 2*M_PI*1.01) {		$yp = floor($yc-($height*sin($a)/2)+$thick);	    } else {		$yp = floor($yc-$height*sin($a)/2);	    }	    $coords.= ", $xp, $yp";	    $a += 0.2;	}			//Add the last point on the arc	$xp = floor($width*cos($ea)/2+$xc);	$yp = floor($yc-$height*sin($ea)/2);	if ($ea >= M_PI && $ea <= 2*M_PI*1.01) {	    $coords.= ", $xp, ".floor($yp+$thick);	}	$coords.= ", $xp, $yp";	$alt='';	if( !empty($this->csimalts[$i]) ) {											    $tmp=sprintf($this->csimalts[$i],$this->data[$i]);	    $alt="alt=\"$tmp\" title=\"$tmp\"";	}	if( !empty($this->csimtargets[$i]) )	    $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\" $alt />\n";    }    function SetLabels($aLabels,$aLblPosAdj="auto") {	$this->labels = $aLabels;	$this->ilabelposadj=$aLblPosAdj;    }	    // Distance from the pie to the labels    function SetLabelMargin($m) {	$this->value->SetMargin($m);    }	    // Show a thin line from the pie to the label for a specific slice    function ShowLabelHint($f=true) {	$this->showlabelhint=$f;    }	    // Set color of hint line to label for each slice    function SetLabelHintColor($c) {	$this->labelhintcolor=$c;    }    function SetHeight($aHeight) {      $this->iThickness = $aHeight;    }// Normalize Angle between 0-360    function NormAngle($a) {	// Normalize anle to 0 to 2M_PI	// 	if( $a > 0 ) {	    while($a > 360) $a -= 360;	}	else {	    while($a < 0) $a += 360;	}	if( $a < 0 )	    $a = 360 + $a;	if( $a == 360 ) $a=0;	return $a;    }    // Draw one 3D pie slice at position ($xc,$yc) with height $z    function Pie3DSlice($img,$xc,$yc,$w,$h,$sa,$ea,$z,$fillcolor,$shadow=0.65) {		// Due to the way the 3D Pie algorithm works we are	// guaranteed that any slice we get into this method	// belongs to either the left or right side of the	// pie ellipse. Hence, no slice will cross 90 or 270	// point.	if( ($sa < 90 && $ea > 90) || ( ($sa > 90 && $sa < 270) && $ea > 270) ) {	    JpGraphError::RaiseL(14003);//('Internal assertion failed. Pie3D::Pie3DSlice');	    exit(1);	}	$p[] = array();	// Setup pre-calculated values	$rsa = $sa/180*M_PI;	// to Rad	$rea = $ea/180*M_PI;	// to Rad	$sinsa = sin($rsa);	$cossa = cos($rsa);	$sinea = sin($rea);	$cosea = cos($rea);	// p[] is the points for the overall slice and	// pt[] is the points for the top pie	// Angular step when approximating the arc with a polygon train.	$step = 0.05;	if( $sa >= 270 ) {	    if( $ea > 360 || ($ea > 0 && $ea <= 90) ) {		if( $ea > 0 && $ea <= 90 ) {		    // Adjust angle to simplify conditions in loops		    $rea += 2*M_PI;		}		$p = array($xc,$yc,$xc,$yc+$z,			   $xc+$w*$cossa,$z+$yc-$h*$sinsa);		$pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);		for( $a=$rsa; $a < 2*M_PI; $a += $step ) {		    $tca = cos($a);		    $tsa = sin($a);		    $p[] = $xc+$w*$tca;		    $p[] = $z+$yc-$h*$tsa;		    $pt[] = $xc+$w*$tca;		    $pt[] = $yc-$h*$tsa;		}		$pt[] = $xc+$w;		$pt[] = $yc;		$p[] = $xc+$w;		$p[] = $z+$yc;		$p[] = $xc+$w;		$p[] = $yc;		$p[] = $xc;		$p[] = $yc;		for( $a=2*M_PI+$step; $a < $rea; $a += $step ) {		    $pt[] = $xc + $w*cos($a);		    $pt[] = $yc - $h*sin($a);		}		    		$pt[] = $xc+$w*$cosea;		$pt[] = $yc-$h*$sinea;		$pt[] = $xc;		$pt[] = $yc;	    }	    else {		$p = array($xc,$yc,$xc,$yc+$z,			   $xc+$w*$cossa,$z+$yc-$h*$sinsa);		$pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);		    		$rea = $rea == 0.0 ? 2*M_PI : $rea;		for( $a=$rsa; $a < $rea; $a += $step ) {		    $tca = cos($a);		    $tsa = sin($a);		    $p[] = $xc+$w*$tca;		    $p[] = $z+$yc-$h*$tsa;		    $pt[] = $xc+$w*$tca;		    $pt[] = $yc-$h*$tsa;		}		$pt[] = $xc+$w*$cosea;		$pt[] = $yc-$h*$sinea;		$pt[] = $xc;		$pt[] = $yc;		    		$p[] = $xc+$w*$cosea;		$p[] = $z+$yc-$h*$sinea;		$p[] = $xc+$w*$cosea;		$p[] = $yc-$h*$sinea;		$p[] = $xc;		$p[] = $yc;	    }	}	elseif( $sa >= 180 ) {	    $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea);	    $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);			    for( $a=$rea; $a>$rsa; $a -= $step ) {		$tca = cos($a);		$tsa = sin($a);		$p[] = $xc+$w*$tca;		$p[] = $z+$yc-$h*$tsa;		$pt[] = $xc+$w*$tca;		$pt[] = $yc-$h*$tsa;	    }	    $pt[] = $xc+$w*$cossa;	    $pt[] = $yc-$h*$sinsa;	    $pt[] = $xc;	    $pt[] = $yc;			    $p[] = $xc+$w*$cossa;	    $p[] = $z+$yc-$h*$sinsa;	    $p[] = $xc+$w*$cossa;	    $p[] = $yc-$h*$sinsa;	    $p[] = $xc;	    $p[] = $yc;		}	elseif( $sa >= 90 ) {	    if( $ea > 180 ) {		$p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea);		$pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);		for( $a=$rea; $a > M_PI; $a -= $step ) {		    $tca = cos($a);		    $tsa = sin($a);		    		    $p[] = $xc+$w*$tca;		    $p[] = $z + $yc - $h*$tsa;		    $pt[] = $xc+$w*$tca;		    $pt[] = $yc-$h*$tsa;		}		$p[] = $xc-$w;		$p[] = $z+$yc;		$p[] = $xc-$w;		$p[] = $yc;		$p[] = $xc;		$p[] = $yc;		$pt[] = $xc-$w;		$pt[] = $z+$yc;		$pt[] = $xc-$w;		$pt[] = $yc;		for( $a=M_PI-$step; $a > $rsa; $a -= $step ) {		    $pt[] = $xc + $w*cos($a);		    $pt[] = $yc - $h*sin($a);		}		$pt[] = $xc+$w*$cossa;		$pt[] = $yc-$h*$sinsa;		$pt[] = $xc;		$pt[] = $yc;	    }	    else { // $sa >= 90 && $ea <= 180		$p = array($xc,$yc,$xc,$yc+$z,			   $xc+$w*$cosea,$z+$yc-$h*$sinea,			   $xc+$w*$cosea,$yc-$h*$sinea,			   $xc,$yc);		$pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea);		for( $a=$rea; $a>$rsa; $a -= $step ) {		    $pt[] = $xc + $w*cos($a);		    $pt[] = $yc - $h*sin($a);		}		$pt[] = $xc+$w*$cossa;		$pt[] = $yc-$h*$sinsa;		$pt[] = $xc;		$pt[] = $yc;	    }	}	else { // sa > 0 && ea < 90	    $p = array($xc,$yc,$xc,$yc+$z,		       $xc+$w*$cossa,$z+$yc-$h*$sinsa,		       $xc+$w*$cossa,$yc-$h*$sinsa,		       $xc,$yc);	    $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa);	    for( $a=$rsa; $a < $rea; $a += $step ) {		$pt[] = $xc + $w*cos($a);		$pt[] = $yc - $h*sin($a);	    }	    $pt[] = $xc+$w*$cosea;	    $pt[] = $yc-$h*$sinea;	    $pt[] = $xc;	    $pt[] = $yc;	}	    	$img->PushColor($fillcolor.":".$shadow);	$img->FilledPolygon($p);	$img->PopColor();	$img->PushColor($fillcolor);	$img->FilledPolygon($pt);	$img->PopColor();    }    function SetStartAngle($aStart) {	if( $aStart < 0 || $aStart > 360 ) {	    JpGraphError::RaiseL(14004);//('Slice start angle must be between 0 and 360 degrees.');	}	$this->startangle = $aStart;    }    // Draw a 3D Pie    function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z,		   $shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) {	//---------------------------------------------------------------------------	// As usual the algorithm get more complicated than I originally	// envisioned. I believe that this is as simple as it is possible	// to do it with the features I want. It's a good exercise to start	// thinking on how to do this to convince your self that all this	// is really needed for the general case.	//	// The algorithm two draw 3D pies without "real 3D" is done in	// two steps.	// First imagine the pie cut in half through a thought line between	// 12'a clock and 6'a clock. It now easy to imagine that we can plot 	// the individual slices for each half by starting with the topmost	// pie slice and continue down to 6'a clock.	// 	// In the algortithm this is done in three principal steps	// Step 1. Do the knife cut to ensure by splitting slices that extends 	// over the cut line. This is done by splitting the original slices into	// upto 3 subslices.	// Step 2. Find the top slice for each half	// Step 3. Draw the slices from top to bottom	//	// The thing that slightly complicates this scheme with all the	// angle comparisons below is that we can have an arbitrary start	// angle so we must take into account the different equivalence classes.	// For the same reason we must walk through the angle array in a 	// modulo fashion.	//	// Limitations of algorithm: 	// * A small exploded slice which crosses the 270 degree point	//   will get slightly nagged close to the center due to the fact that	//   we print the slices in Z-order and that the slice left part	//   get printed first and might get slightly nagged by a larger	//   slice on the right side just before the right part of the small	//   slice. Not a major problem though. 	//---------------------------------------------------------------------------    	// Determine the height of the ellippse which gives an	// indication of the inclination angle	$h = ($angle/90.0)*$d;	$sum = 0;	for($i=0; $i<count($data); ++$i ) {	    $sum += $data[$i];	}		// Special optimization	if( $sum==0 ) return;	if( $this->labeltype == 2 ) {	    $this->adjusted_data = $this->AdjPercentage($data);	}	// Setup the start	$accsum = 0;	$a = $startangle;	$a = $this->NormAngle($a);	// 	// Step 1 . Split all slices that crosses 90 or 270	//	$idx=0;	$adjexplode=array(); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -