PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/graphics/jpgraph/jpgraph_pie.php

https://github.com/robertatakenaka/Web
PHP | 346 lines | 237 code | 60 blank | 49 comment | 39 complexity | 26f3cacd6d1761b856a75be2fccb7eda MD5 | raw file
  1. <?php
  2. /*=======================================================================
  3. // File: JPGRAPH_PIE.PHP
  4. // Description: Pie plot extension for JpGraph
  5. // Created: 2001-02-14
  6. // Last edit: 29/04/01 12:41
  7. // Author: Johan Persson (johanp@aditus.nu)
  8. // Ver: 1.2.2
  9. //
  10. // License: This code is released under GPL 2.0
  11. //
  12. //========================================================================
  13. */
  14. //===================================================
  15. // CLASS PiePlot
  16. // Description:
  17. //===================================================
  18. class PiePlot {
  19. var $posx=0.5,$posy=0.5;
  20. var $radius=0.3;
  21. var $explode_slice=-1;
  22. var $labels, $legends=null;
  23. var $data=null;
  24. var $title;
  25. var $startangle=0;
  26. var $weight=1, $color="black";
  27. var $font_family=FONT1,$font_style=FS_NORMAL,$font_size=12,$font_color="black";
  28. var $legend_margin=6,$show_labels=true;
  29. var $precision=1,$show_psign=true;
  30. var $themearr=array(
  31. "earth" => array(10,34,40,45,46,62,63,134,74,77,120,136,141,168,180,209,218,346,395,89,430),
  32. "pastel" => array(27,38,42,58,66,79,105,110,128,147,152,230,236,240,331,337,405,415),
  33. "water" => array(8,370,10,40,335,56,213,237,268,14,326,387,24,388),
  34. "sand" => array(27,168,34,170,19,50,65,72,131,209,46,393));
  35. var $theme="earth",$colors=array();
  36. var $setslicecolors=array();
  37. //---------------
  38. // CONSTRUCTOR
  39. function PiePlot(&$data) {
  40. $this->data = $data;
  41. $this->title = new Text("");
  42. $this->title->SetFont(FONT1,FS_BOLD);
  43. }
  44. //---------------
  45. // PUBLIC METHODS
  46. function SetCenter($x,$y=0.5) {
  47. $this->posx = $x;
  48. $this->posy = $y;
  49. }
  50. function SetTheme($t) {
  51. if( in_array($t,array_keys($this->themearr)) )
  52. $this->theme = $t;
  53. else
  54. die("JpGraph Error: Unknown theme: $t");
  55. }
  56. function ExplodeSlice($e) {
  57. $this->explode_slice=$e;
  58. }
  59. function SetSliceColors($c) {
  60. $this->setslicecolors = $c;
  61. }
  62. function SetStartAngle($a) {
  63. assert($a>=0 && $a<2*M_PI);
  64. $this->startangle = $a;
  65. }
  66. function SetFont($family,$style=FS_NORMAL,$size=12) {
  67. $this->font_family=$family;
  68. $this->font_style=$style;
  69. $this->font_size=$size;
  70. }
  71. // Size in percentage
  72. function SetSize($size) {
  73. assert($size>0 && $size<=0.5);
  74. $this->radius = $size;
  75. }
  76. function SetFontColor($color) {
  77. $this->font_color = $color;
  78. }
  79. function SetLegends($l) {
  80. $this->legends = $l;
  81. }
  82. function HideLabels($f=true) {
  83. $this->show_labels = !$f;
  84. }
  85. function Legend(&$graph) {
  86. $colors = array_keys($graph->img->rgb->rgb_table);
  87. sort($colors);
  88. $ta=$this->themearr[$this->theme];
  89. if( $this->setslicecolors==null )
  90. $numcolors=count($ta);
  91. else
  92. $numcolors=count($this->setslicecolors);
  93. $i=0;
  94. if( count($this->legends)>0 ) {
  95. foreach( $this->legends as $l ) {
  96. if( $this->setslicecolors==null )
  97. $graph->legend->Add($l,$colors[$ta[$i%$numcolors]]);
  98. else
  99. $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors]);
  100. ++$i;
  101. if( $i==count($this->data) ) return;
  102. }
  103. }
  104. }
  105. function SetPrecision($p,$psign=true) {
  106. $this->precision = $p;
  107. $this->show_psign=$psign;
  108. }
  109. function Stroke(&$img) {
  110. $colors = array_keys($img->rgb->rgb_table);
  111. sort($colors);
  112. $ta=$this->themearr[$this->theme];
  113. if( $this->setslicecolors==null )
  114. $numcolors=count($ta);
  115. else
  116. $numcolors=count($this->setslicecolors);
  117. // Draw the slices
  118. $sum=0;
  119. foreach($this->data as $d)
  120. $sum += $d;
  121. // Format the titles for each slice
  122. for( $i=0; $i<count($this->data); ++$i) {
  123. $l = round(100*$this->data[$i]/$sum,$this->precision);
  124. $l = sprintf("%01.".$this->precision."f",$l);
  125. if( $this->show_psign ) $l .= "%";
  126. $this->labels[$i]=$l;
  127. }
  128. // Set up the pic-circle
  129. $radius = floor($this->radius*min($img->width,$img->height));
  130. $xc = $this->posx*$img->width;
  131. $yc = $this->posy*$img->height;
  132. // Draw the first slice first line
  133. $img->SetColor($this->color);
  134. $img->SetLineWeight($this->weight);
  135. $a = $this->startangle;
  136. $x = round(cos($a)*$radius);
  137. $y = round(sin($a)*$radius);
  138. $img->Line($xc,$yc,$xc+$x,$yc-$y);
  139. if( $this->explode_slice>=0 ) {
  140. if( $this->explode_slice>0 )
  141. $p = $this->explode_slice-1;
  142. else
  143. $p = count($this->data)-1;
  144. $acc=0;
  145. for($i=0; $i<$this->explode_slice; ++$i)
  146. $acc += $this->data[$i];
  147. $start = 360-($acc/$sum)*360;
  148. $end = 360-(($this->data[$this->explode_slice]/$sum)*360+($acc/$sum)*360);
  149. $img->Arc($xc,$yc,2*$radius,2*$radius,$start,$end);
  150. }
  151. else
  152. $img->Circle($xc,$yc,$radius);
  153. for($i=0; $i<count($this->data); ++$i) {
  154. $img->SetColor($this->color);
  155. $d = $this->data[$i];
  156. $la = $a + M_PI*$d/$sum;
  157. $old_a = $a;
  158. $a += 2*M_PI*$d/$sum;
  159. $x = round(cos($a)*$radius);
  160. $y = round(sin($a)*$radius);
  161. // Don't stroke last line since this is the same as the first
  162. // line drawn but due to rounding error it might be just a
  163. // tad pixel off and may not look as good.
  164. if( $i<count($this->data)-1)
  165. $img->Line($xc,$yc,$xc+$x,$yc-$y);
  166. if( $this->setslicecolors==null )
  167. $slicecolor=$colors[$ta[$i%$numcolors]];
  168. else
  169. $slicecolor=$this->setslicecolors[$i%$numcolors];
  170. if( $i == $this->explode_slice ) {
  171. $this->explode_slice($img,$slicecolor,$this->labels[$i],$xc,$yc,$radius,$old_a,$a);
  172. }
  173. else {
  174. if( $this->show_labels )
  175. $this->StrokeLabels($this->labels[$i],$img,$xc,$yc,$la,$radius);
  176. $img->SetColor($slicecolor);
  177. $xf = cos($la)*$radius/2;
  178. $yf = sin($la)*$radius/2;
  179. $img->Fill($xf+$xc,$yc-$yf);
  180. }
  181. }
  182. // Adjust title position
  183. $this->title->Pos($xc,$yc-$img->GetFontHeight()-$radius,"center","bottom");
  184. $this->title->Stroke($img);
  185. }
  186. //---------------
  187. // PRIVATE METHODS
  188. function explode_slice($img,$color,$label,$xc,$yc,$r,$old_a,$a) {
  189. $extract=0.3;
  190. $am = abs($a-$old_a)/2+$old_a;
  191. $xc = cos($am)*$r*$extract+$xc;
  192. $yc = $yc - sin($am)*$r*$extract;
  193. $x1 = cos($old_a)*$r + $xc;
  194. $x2 = cos($a)*$r + $xc;
  195. $y1 = $yc - sin($old_a)*$r;
  196. $y2 = $yc - sin($a)*$r;
  197. $xf=cos($am)*$r*0.5+$xc;
  198. $yf=$yc-sin($am)*$r*0.5;
  199. $old_a *= 360/(2*M_PI);
  200. $a *= 360/(2*M_PI);
  201. $start = 360-$a;
  202. $end = $start + abs($old_a-$a);
  203. $img->SetColor($this->color);
  204. $img->Arc($xc,$yc,$r*2,$r*2,$start,$end);
  205. $img->Line($xc,$yc,$x1,$y1);
  206. $img->Line($xc,$yc,$x2,$y2);
  207. $img->SetColor($color);
  208. $img->Fill($xf,$yf);
  209. $this->StrokeLabels($label,$img,$xc,$yc,$am,$r);
  210. }
  211. function StrokeLabels($label,$img,$xc,$yc,$a,$r) {
  212. // Draw title of this axis
  213. $img->SetFont($this->font_family,$this->font_style,$this->font_size);
  214. $img->SetColor($this->font_color);
  215. $img->SetTextAlign("left","top");
  216. $marg=6;
  217. $r += $img->GetFontHeight()/2;
  218. $xt=round($r*cos($a)+$xc);
  219. $yt=round($yc-$r*sin($a));
  220. // Position the axis title.
  221. // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
  222. // that intersects with the extension of the corresponding axis. The code looks a little
  223. // bit messy but this is really the only way of having a reasonable position of the
  224. // axis titles.
  225. $h=$img->GetTextHeight($label);
  226. $w=$img->GetTextWidth($label);
  227. while( $a > 2*M_PI ) $a -= 2*M_PI;
  228. if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
  229. if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
  230. if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
  231. if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
  232. if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
  233. if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI);
  234. if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
  235. if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
  236. if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
  237. $img->StrokeText($xt-$dx*$w,$yt-$dy*$h,$label);
  238. }
  239. } // Class
  240. //===================================================
  241. // CLASS PieGraph
  242. // Description:
  243. //===================================================
  244. class PieGraph extends Graph {
  245. var $posx, $posy, $radius;
  246. var $legends=array();
  247. var $plots=array();
  248. //---------------
  249. // CONSTRUCTOR
  250. function PieGraph($width=300,$height=200,$cachedName="") {
  251. $this->Graph($width,$height,$cachedName,0);
  252. $this->posx=$width/2;
  253. $this->posy=$height/2;
  254. $this->SetColor(array(255,255,255));
  255. }
  256. //---------------
  257. // PUBLIC METHODS
  258. function Add(&$pie) {
  259. $this->plots[] = $pie;
  260. }
  261. function SetColor($c) {
  262. $this->SetMarginColor($c);
  263. }
  264. // Method description
  265. function Stroke() {
  266. $this->StrokeFrame();
  267. foreach($this->plots as $p)
  268. $p->Stroke($this->img);
  269. foreach( $this->plots as $p)
  270. $p->Legend($this);
  271. $this->legend->Stroke($this->img);
  272. $this->title->Center($this->img->left_margin,$this->img->width-$this->img->right_margin,5);
  273. $this->title->Stroke($this->img);
  274. // Stroke texts
  275. if( $this->texts != null )
  276. foreach( $this->texts as $t) {
  277. $t->x *= $this->img->width;
  278. $t->y *= $this->img->height;
  279. $t->Stroke($this->img);
  280. }
  281. // Finally output the image
  282. $this->cache->PutAndStream($this->img,$this->cache_name);
  283. }
  284. } // Class
  285. /* EOF */
  286. ?>