php 打造完美柱状图

&lt;?php<br /> /* <br /> * 定义 柱状图(柱形图) 类<br /> * 注意,使用前请确保字体路径存在并允许访问,如果出错,还要检查在php.ini配置中的open_basedir项,如果没此路径请添加,或在程序中设置包含<br /> * 智能化的柱状图程序,用于报表等<br /> ***/<br /> <br /> define(&quot;DEFAULT_FONT_PATH&quot;, &quot;c:/windows/fonts/simhei.ttf&quot;);<br /> class SingleBar<br /> {<br /> private $_x;<br /> private $_y;<br /> private $_h;<br /> public $_l = 50;<br /> private $_w = null;<br /> private $_srcPoints = array();<br /> private $_points = array();<br /> <br /> public function __construct($x, $y, $h, $l = 50, $w = null)<br /> {<br /> $this-&gt;_x = $x;<br /> $this-&gt;_y = $y;<br /> $this-&gt;_h = $h;<br /> $this-&gt;_l = $l;<br /> $this-&gt;_w = $w;<br /> $this-&gt;_srcPoints = $this-&gt;getSrcPoints();<br /> $this-&gt;_points = $this-&gt;getPoints();<br /> }<br /> <br /> public function getSrcPoints()<br /> {<br /> return array(<br /> array($this-&gt;_x , $this-&gt;_y),<br /> array($this-&gt;_x+$this-&gt;_l , $this-&gt;_y),<br /> array($this-&gt;_x+(1.35*$this-&gt;_l), $this-&gt;_y-(0.35*$this-&gt;_l)),<br /> array($this-&gt;_x+(0.35*$this-&gt;_l), $this-&gt;_y-(0.35*$this-&gt;_l)),<br /> array($this-&gt;_x , $this-&gt;_y+$this-&gt;_h),<br /> array($this-&gt;_x+$this-&gt;_l , $this-&gt;_y+$this-&gt;_h),<br /> array($this-&gt;_x+(1.35*$this-&gt;_l), $this-&gt;_y+$this-&gt;_h-(0.35*$this-&gt;_l)) <br /> );<br /> }<br /> <br /> public function getPoints()<br /> {<br /> $points = array();<br /> foreach($this-&gt;_srcPoints as $key =&gt; $val)<br /> {<br /> $points[] = $val[0];<br /> $points[] = $val[1];<br /> }<br /> return $points;<br /> }<br /> <br /> public function getTopPoints()<br /> {<br /> return array_slice($this-&gt;_points, 0, 8); //顶坐标<br /> }<br /> <br /> public function getBelowPoints()<br /> {<br /> return array_merge(array_slice($this-&gt;_points, 0, 2), array_slice($this-&gt;_points, 8, 4), array_slice($this-&gt;_points, 2, 2)); //下坐标<br /> }<br /> <br /> public function getRightSidePoints()<br /> {<br /> return array_merge(array_slice($this-&gt;_points, 2, 2), array_slice($this-&gt;_points, 10, 4), array_slice($this-&gt;_points, 4, 2)); //右侧坐标<br /> }<br /> <br /> public function draw($image, $topColor, $belowColor, $sideColor, $borderColor = null, $type = 'LEFT')<br /> {<br /> if (is_null($borderColor))<br /> {<br /> $borderColor = 0xcccccc;<br /> }<br /> <br /> $top_rgb = $this-&gt;getRGB($topColor);<br /> $below_rgb = $this-&gt;getRGB($belowColor);<br /> $side_rgb = $this-&gt;getRGB($sideColor);<br /> $top_color = imagecolorallocate($image, $top_rgb['R'], $top_rgb['G'], $top_rgb['B']);<br /> $below_color = imagecolorallocate($image, $below_rgb['R'], $below_rgb['G'], $below_rgb['B']);<br /> $side_color = imagecolorallocate($image, $side_rgb['R'], $side_rgb['G'], $side_rgb['B']);<br /> <br /> imagefilledpolygon($image, $this-&gt;getTopPoints(), 4, $top_color); //画顶面<br /> imagepolygon($image, $this-&gt;getTopPoints(), 4, $borderColor); //画顶面边线<br /> <br /> imagefilledpolygon($image, $this-&gt;getBelowPoints(), 4, $below_color); //画下面<br /> imagepolygon($image, $this-&gt;getBelowPoints(), 4, $borderColor); //画下面边线<br /> <br /> if ($type == 'LEFT')<br /> {<br /> imagefilledpolygon($image, $this-&gt;getRightSidePoints(), 4, $side_color); //画右侧面<br /> imagepolygon($image, $this-&gt;getRightSidePoints(), 4, $borderColor); //画侧面边线<br /> } <br /> }<br /> <br /> public function getRGB($color)<br /> {<br /> $ar = array();<br /> $color = hexdec($color);<br /> $ar['R'] = ($color&gt;&gt;16) &amp; 0xff;<br /> $ar['G'] = ($color&gt;&gt;8) &amp; 0xff;<br /> $ar['B'] = ($color) &amp; 0xff;<br /> return $ar;<br /> }<br /> }<br /> <br /> class Bar<br /> {<br /> private $_W;<br /> private $_H;<br /> private $_bgColor = &quot;ffffff&quot;;<br /> private $_barHeights = array();<br /> private $_barTexts = array();<br /> private $_barColors = array();<br /> public $_title;<br /> public $_paddingTop = 30;<br /> public $_paddingBottom = 100;<br /> public $_paddingLeft = 45;<br /> public $_paddingRight = 2;<br /> public $_barL = 50;<br /> public $image;<br /> <br /> public function __construct($imgW, $imgH, $barHeights, $barTexts = null, $barColors = null)<br /> {<br /> $this-&gt;_W = $imgW;<br /> $this-&gt;_H = $imgH;<br /> $this-&gt;_barHeights = $barHeights;<br /> $this-&gt;_barTexts = $barTexts;<br /> $this-&gt;_barColors = $barColors;<br /> $this-&gt;_paddingBottom = $this-&gt;resetPaddingBottom();<br /> $this-&gt;_H = $this-&gt;resetHeight();<br /> $this-&gt;image = imagecreatetruecolor($this-&gt;_W, $this-&gt;_H);<br /> }<br /> <br /> public function stroke()<br /> {<br /> $this-&gt;drawBg();<br /> $this-&gt;drawBars();<br /> $this-&gt;drawTitle();<br /> $this-&gt;drawLables();<br /> ob_start();<br /> //header(&quot;Content-type: image/png&quot;);<br /> //imagepng($this-&gt;image);<br /> header(&quot;Content-type: &quot; . image_type_to_mime_type(IMAGETYPE_JPEG));<br /> imagejpeg($this-&gt;image);<br /> imagedestroy($this-&gt;image);<br /> }<br /> <br /> public function drawBg()<br /> {<br /> $img_w = $this-&gt;_W;<br /> $img_h = $this-&gt;_H;<br /> $paddingTop = $this-&gt;_paddingTop;<br /> $paddingBottom = $this-&gt;_paddingBottom;<br /> $paddingLeft = $this-&gt;_paddingLeft;<br /> $paddingRight = $this-&gt;_paddingRight;<br /> $rgb = $this-&gt;getRGB($this-&gt;_bgColor);<br /> $bg = imagecolorallocate($this-&gt;image,$rgb['R'], $rgb['G'], $rgb['B']);<br /> imagefilledrectangle($this-&gt;image, 0, 0, $img_w, $img_h, $bg);<br /> $side_bg = imagecolorallocatealpha($this-&gt;image, 220, 220, 220, 75);<br /> $side_bg2 = imagecolorallocate($this-&gt;image, 220, 220, 220);<br /> $border_color = imagecolorallocate($this-&gt;image, 190, 190, 190);<br /> $line_color = imagecolorallocate($this-&gt;image, 236, 236, 236);<br /> $dial_color = imagecolorallocate($this-&gt;image, 131, 131, 131);<br /> <br /> $x1 = $paddingLeft;<br /> $y1 = $paddingTop;<br /> $x2 = $img_w - $paddingRight;<br /> $y2 = $img_h - $paddingBottom;<br /> imagerectangle($this-&gt;image, $x1, $y1, $x2, $y2, $border_color);<br /> imagefilledpolygon($this-&gt;image, array($x1-5,$y1+10, $x1-5,$y2+10, $x1,$y2, $x1,$y1), 4, $side_bg);<br /> imagepolygon($this-&gt;image, array($x1-5,$y1+10, $x1-5,$y2+10, $x1,$y2, $x1,$y1), 4, $border_color);<br /> imagefilledpolygon($this-&gt;image, array($x1-5,$y2+10, $x2-5,$y2+10, $x2,$y2, $x1,$y2), 4, $side_bg);<br /> imagepolygon($this-&gt;image, array($x1-5,$y2+10, $x2-5,$y2+10, $x2,$y2, $x1,$y2), 4, $border_color);<br /> imageline($this-&gt;image, $x1, $y2, $x2, $y2, $side_bg2);<br /> <br /> $total_h = $img_h - $paddingTop - $paddingBottom;<br /> $every_h = $total_h/11;<br /> for($i=1; $i&lt;=10; $i++)<br /> {<br /> imageline($this-&gt;image, $x1, $y1+($every_h*$i), $x2, $y1+($every_h*$i), $line_color); //画网线<br /> }<br /> <br /> $max_h = max($this-&gt;_barHeights);<br /> for($i=1; $i&lt;=10; $i++)<br /> {<br /> $value = $max_h - (($max_h/10)*($i-1));<br /> $value = strval($value);<br /> $str_w = strlen($value)*5;<br /> imageline($this-&gt;image, $x1-5-3, $y1+10+($every_h*$i), $x1-3+1, $y1+10+($every_h*$i), $dial_color); //画刻度线<br /> imagestring($this-&gt;image, 3, $x1-5-3-$str_w-1, $y1+10+($every_h*$i)-5, $value, 0x000000);<br /> }<br /> }<br /> <br /> <br /> public function drawBars()<br /> {<br /> $counts = count($this-&gt;_barHeights);<br /> if (empty($this-&gt;_barColors))<br /> {<br /> $color = $this-&gt;setColor();<br /> $this-&gt;_barColors = array_slice($color, 0, $counts);<br /> //shuffle($this-&gt;_barColors);<br /> }<br /> $every_w = ($this-&gt;_W - $this-&gt;_paddingLeft - $this-&gt;_paddingRight)/$counts; //每一段宽<br /> $barL = $every_w;<br /> $barL = ($barL &gt; $this-&gt;_barL*1.35+6) ? $this-&gt;_barL : $barL/1.35 - 6;<br /> $max_h = max($this-&gt;_barHeights);<br /> $ruler_h = $this-&gt;_H - $this-&gt;_paddingTop - $this-&gt;_paddingBottom; //标尺总高度<br /> $stander_h = $ruler_h - ($ruler_h/11); //标尺10等分的高度<br /> $i = 0;<br /> foreach ($this-&gt;_barHeights as $val)<br /> {<br /> $h = ($stander_h/$max_h)*$val;<br /> $x = $this-&gt;_paddingLeft + ($every_w*$i) + (($every_w - ($barL*1.35))/2);;<br /> $y = $this-&gt;_H - $this-&gt;_paddingBottom + 10 - $h;<br /> //$t_color = $this-&gt;_barColors[$i];<br /> $b_color = $this-&gt;_barColors[$i];<br /> //$s_color = $this-&gt;_barColors[$i];<br /> <br /> <br /> $rgb = $this-&gt;getRGB($this-&gt;_barColors[$i]);<br /> $R = $rgb['R'] * 0.7;<br /> $G = $rgb['G'] * 0.7;<br /> $B = $rgb['B'] * 0.7;<br /> <br /> $c1 = $R &gt; 0 ? dechex($R) : '00';<br /> $c2 = $G &gt; 0 ? dechex($G) : '00';<br /> $c3 = $B &gt; 0 ? dechex($B) : '00';<br /> <br /> $t_color = $b_color;<br /> $s_color = $c1. $c2 . $c3;<br /> <br /> $SingleBar = new SingleBar($x, $y, $h, $barL);<br /> $SingleBar-&gt;draw($this-&gt;image, $t_color, $b_color, $s_color);<br /> $i++;<br /> }<br /> }<br /> <br /> public function drawTitle()<br /> {<br /> if (empty($this-&gt;_title))<br /> {<br /> return;<br /> }<br /> $font = 5;<br /> $font_w = imagefontwidth($font);<br /> $len = strlen($this-&gt;_title);<br /> $x = ($this-&gt;_W + $this-&gt;_paddingLeft - $this-&gt;_paddingRight)/2;<br /> $x -= ($len*$font_w)/2;<br /> $y = ($this-&gt;_paddingTop - $font_w)/2 + 12;<br /> //imagestring($this-&gt;image, $font, $x, $y, $title, 0x000000);<br /> imagettftext($this-&gt;image, 12, 0, $x, $y, 0x000000, DEFAULT_FONT_PATH, $this-&gt;_title);<br /> }<br /> <br /> public function drawLables()<br /> {<br /> $x1 = $this-&gt;_paddingLeft - 5;<br /> $y1 = $this-&gt;_H - $this-&gt;_paddingBottom + 20;<br /> $x2 = $this-&gt;_W - $this-&gt;_paddingRight;<br /> $y2 = $this-&gt;_H - 10;<br /> //imagefilledrectangle($this-&gt;image, $x1, $y1, $x2, $y2, 0xffffff);<br /> imagerectangle($this-&gt;image, $x1, $y1, $x2, $y2, 0x000000);<br /> $space = 5;<br /> $x = $x1 + 3;<br /> $y = $y1 + 3;<br /> foreach ($this-&gt;_barTexts as $key =&gt; $val)<br /> {<br /> $color = $this-&gt;_barColors[$key];<br /> $rgb = $this-&gt;getRGB($color);<br /> $bg = imagecolorallocate($this-&gt;image,$rgb['R'], $rgb['G'], $rgb['B']);<br /> imagefilledrectangle($this-&gt;image, $x, $y, $x+12, $y+12, $bg); //绘12*12的矩形<br /> imagerectangle($this-&gt;image, $x, $y, $x+12, $y+12, 0x000000); //绘12*12的矩形框<br /> imagettftext($this-&gt;image, 12, 0, $x+12+3, $y+12, 0x000000, DEFAULT_FONT_PATH, $val);<br /> $x += 12 + $space + (strlen($val)*8) + $space;<br /> if ($x + (strlen($val)*8) &gt;= $this-&gt;_W - $this-&gt;_paddingLeft - $this-&gt;_paddingRight)<br /> {<br /> $x = $x1 + 3;<br /> $y = $y + 12 + 3;<br /> }<br /> }<br /> }<br /> <br /> public function resetPaddingBottom()<br /> {<br /> $ruler_w = $this-&gt;_W - $this-&gt;_paddingLeft - $this-&gt;_paddingRight;<br /> $label_w = $this-&gt;getLableTotalWidth();<br /> $lines = ceil($label_w / $ruler_w);<br /> $h = 12 * $lines + (3 * ($lines + 1)) + 30;<br /> return $h;<br /> }<br /> <br /> public function resetHeight()<br /> {<br /> $padding_bottom = $this-&gt;resetPaddingBottom();<br /> if ($this-&gt;_H - $padding_bottom &lt; 222)<br /> {<br /> return 222 + $padding_bottom;<br /> }<br /> return $this-&gt;_H;<br /> }<br /> <br /> <br /> public function getLableTotalWidth()<br /> {<br /> $counts = count($this-&gt;_barTexts);<br /> $space = 5;<br /> $total_len = 0;<br /> foreach ($this-&gt;_barTexts as $val)<br /> {<br /> $total_len += strlen($val);<br /> }<br /> <br /> $tx_w = ($total_len * 9) + ((12 + 3 + $space) * $counts);<br /> return $tx_w;<br /> }<br /> <br /> public function setBg($color)<br /> {<br /> $this-&gt;_bgColor = $color;<br /> }<br /> <br /> public function setTitle($title)<br /> {<br /> $this-&gt;_title = $title;<br /> }<br /> <br /> public function setColor()<br /> {<br /> $ar = array('ff', '00', '33', '66', '99', 'cc');<br /> $color = array();<br /> for ($i=0; $i&lt;6; $i++)<br /> {<br /> for ($j=0; $j&lt;6; $j++)<br /> {<br /> for($k=0; $k&lt;6; $k++)<br /> {<br /> $color[] = $ar[$i] . $ar[$j] . $ar[$k];<br /> }<br /> }<br /> }<br /> <br /> $color2 = array();<br /> for ($i=1; $i&lt;216; $i += 4)<br /> {<br /> $color2[] = $color[$i];<br /> }<br /> <br /> return $color2;<br /> }<br /> <br /> public function getRGB($color)<br /> {<br /> $ar = array();<br /> $color = hexdec($color);<br /> $ar['R'] = ($color&gt;&gt;16) &amp; 0xff;<br /> $ar['G'] = ($color&gt;&gt;8) &amp; 0xff;<br /> $ar['B'] = ($color) &amp; 0xff;<br /> return $ar;<br /> }<br /> }<br /> <br /> /***/<br /> $bar = new Bar(500, 300, array(600, 300, 30, 500, 400, 250, 350, 360), array('AAAAA', 'BBBBB', 'CCCCC', 'DDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGGG', 'HHHHHHHHH'));<br /> $bar-&gt;setTitle('打造完美柱状图!');<br /> $bar-&gt;stroke();<br /> /***/<br /> ?&gt;
RangeTime:0.008481s
RangeMem:219.6 KB
返回顶部 留言