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

📄 jpgraph_pie3d.php

📁 极限网络智能办公系统 Office Automation V3.0官方100%源代码.
💻 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 41 2005-06-06 10:46:10Z ljp $ 
// 
// Copyright (c) Aditus Consulting. All rights reserved. 
//======================================================================== 
*/ 

//=================================================== 
// CLASS PiePlot3D 
// Description: Plots a 3D pie with a specified projection 
// angle between 20 and 70 degrees. 
//=================================================== 
class PiePlot3D extends PiePlot { 
var $labelhintcolor="red",$showlabelhint=true; 
var $angle=50;      
var $edgecolor="", $edgeweight=1; 
var $iThickness=false; 
      
//--------------- 
// CONSTRUCTOR 
function PiePlot3d(&$data) { 
     $this->radius = 0.5; 
     $this->data = $data; 
     $this->title = new Text(""); 
     $this->title->SetFont(FF_FONT1,FS_BOLD); 
     $this->value = new DisplayValue(); 
     $this->value->Show(); 
     $this->value->SetFormat('%.0f%%'); 
} 

//--------------- 
// PUBLIC METHODS      
      
// Set label arrays 
function SetLegends($aLegend) { 
     $this->legends = array_reverse($aLegend); 
} 

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,$aWeight=1) { 
     $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; 
} 

function AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle 

     $sa *= M_PI/180; 
     $ea *= M_PI/180; 

     //add coordinates of the centre to the map 
     $coords = "$xc, $yc"; 

     //add coordinates of the first point on the arc to the map 
     $xp = floor($width*cos($sa)/2+$xc); 
     $yp = floor($yc-$height*sin($sa)/2); 
     $coords.= ", $xp, $yp"; 

     //If on the front half, add the thickness offset 
     if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { 
      $yp = floor($yp+$thick); 
      $coords.= ", $xp, $yp"; 
     } 
           
     //add coordinates every 0.2 radians 
     $a=$sa+0.2; 
     while ($a<$ea) { 
      $xp = floor($width*cos($a)/2+$xc); 
      if ($a >= M_PI && $a <= 2*M_PI*1.01) { 
          $yp = floor($yc-($height*sin($a)/2)+$thick); 
      } else { 
          $yp = floor($yc-$height*sin($a)/2); 
      } 
      $coords.= ", $xp, $yp"; 
      $a += 0.2; 
     } 
           
     //Add the last point on the arc 
     $xp = floor($width*cos($ea)/2+$xc); 
     $yp = floor($yc-$height*sin($ea)/2); 


     if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { 
      $coords.= ", $xp, ".floor($yp+$thick); 
     } 
     $coords.= ", $xp, $yp"; 
     $alt=''; 
     if( !empty($this->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::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; 
} 

// Draw a 3D Pie 
function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z, 
           $shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) { 

     //--------------------------------------------------------------------------- 
     // As usual the algorithm get more complicated than I originally 
     // envisioned. I believe that this is as simple as it is possible 
     // to do it with the features I want. It's a good exercise to start 
     // thinking on how to do this to convince your self that all this 
     // is really needed for the general case. 
     // 
     // The algorithm two draw 3D pies without "real 3D" is done in 
     // two steps. 
     // First imagine the pie cut in half through a thought line between 
     // 12'a clock and 6'a clock. It now easy to imagine that we can plot 
     // the individual slices for each half by starting with the topmost 
     // pie slice and continue down to 6'a clock. 
     // 
     // In the algortithm this is done in three principal steps 
     // Step 1. Do the knife cut to ensure by splitting slices that extends 
     // over the cut line. This is done by splitting the original slices into 
     // upto 3 subslices. 
     // Step 2. Find the top slice for each half 
     // Step 3. Draw the slices from top to bottom 
     // 
     // The thing that slightly complicates this scheme with all the 
     // angle comparisons below is that we can have an arbitrary start 
     // angle so we must take into account the different equivalence classes. 
     // For the same reason we must walk through the angle array in a 
     // modulo fashion. 
     // 
     // Limitations of algorithm: 
     // * A small exploded slice which crosses the 270 degree point 
     // will get slightly nagged close to the center due to the fact that 
     // we print the slices in Z-order and that the slice left part 
     // get printed first and might get slightly nagged by a larger 
     // slice on the right side just before the right part of the small 
     // slice. Not a major problem though. 
     //--------------------------------------------------------------------------- 


     // Determine the height of the ellippse which gives an 
     // indication of the inclination angle 
     $h = ($angle/90.0)*$d; 
     $sum = 0; 
     for($i=0; $i<count($data); ++$i ) { 
      $sum += $data[$i]; 
     } 
      
     // Special optimization 
     if( $sum==0 ) return; 

     if( $this->labeltype == 2 ) { 
      $this->adjusted_data = $this->AdjPercentage($data); 
     } 

     // Setup the start 
     $accsum = 0; 
     $a = $startangle; 
     $a = $this->NormAngle($a); 

     // 
     // Step 1 . Split all slices that crosses 90 or 270 
     // 
     $idx=0; 
     $adjexplode=array(); 
     $numcolors = count($colors); 

⌨️ 快捷键说明

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