تالار گفتمان nCIS.ir

نسخه‌ی کامل: رسم نمودار با PHP
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
<?php
    // Prevent direct access
    if(realpath($_SERVER['SCRIPT_FILENAME']) == realpath(__FILE__)) {
        header('location: index.php');
        exit();
    }
    function chart(
        $title      = NULL,
        $values     = NULL,
        $filename   = NULL,
        $width      = NULL,
        $height     = NULL,
        $min        = NULL,
        $max        = NULL,
        $scale      = NULL,
        $showvalues = NULL,
        $fontsize   = NULL,
        $fontcolor  = NULL,
        $backcolor  = NULL,
        $fillcolor  = NULL,
        $linecolor  = NULL,
        $dotscolor  = NULL,
        $gridcolor  = NULL,
        $textcolor  = NULL
    ) {
        // Default configuration
        if(is_null($title))      { $title = 'Chart';                  }
        if(is_null($values))     { $values = array();                 }
        if(is_null($filename))   { $filename = 'chart.png';           }
        if(is_null($width))      { $width = 640;                      }
        if(is_null($height))     { $height = 480;                     }
        if(is_null($min))        { $min = 0;                          }
        if(is_null($max))        { $max = 100;                        }
        if(is_null($scale))      { $scale = 25;                       }
        if(is_null($showvalues)) { $showvalues = true;                }
        if(is_null($fontsize))   { $fontsize = 10;                    }
        if(is_null($fontcolor))  { $fontcolor = array(127,   0,   0); }
        if(is_null($backcolor))  { $backcolor = array(255, 255, 255); }
        if(is_null($fillcolor))  { $fillcolor = array(191, 191, 191); }
        if(is_null($linecolor))  { $linecolor = array(  0,   0,   0); }
        if(is_null($dotscolor))  { $dotscolor = array(  0, 127,   0); }
        if(is_null($gridcolor))  { $gridcolor = array(127, 127, 127); }
        if(is_null($textcolor))  { $textcolor = array(  0,   0, 127); }
        // Internal configuration
        $chart_bottom = floor($height * 0.85);
        $chart_left   = floor($width  * 0.15);
        $chart_right  = floor($width  * 0.95);
        $chart_top    = floor($height * 0.05);
        $cx           = floor($width  / 2   );
        $cy           = floor($height / 2   );
        $scale_x      = floor(($chart_right - $chart_left) / (count($values) + 1));
        $scale_y      = floor(($chart_bottom - $chart_top) / (($max - $min) / $scale));
        $font_regular = 'tahoma.ttf';
        $font_bold    = 'tahoma_bold.ttf';
        $keys         = array_keys($values);
        $count        = count($keys);
        // Main function
        $result = true;
        $im = @imagecreatetruecolor($width, $height);
        if($im !== false) {
            $back = imagecolorallocate($im, $backcolor[0], $backcolor[1], $backcolor[2]);
            $dots = imagecolorallocate($im, $dotscolor[0], $dotscolor[1], $dotscolor[2]);
            $fill = imagecolorallocate($im, $fillcolor[0], $fillcolor[1], $fillcolor[2]);
            $font = imagecolorallocate($im, $fontcolor[0], $fontcolor[1], $fontcolor[2]);
            $grid = imagecolorallocate($im, $gridcolor[0], $gridcolor[1], $gridcolor[2]);
            $line = imagecolorallocate($im, $linecolor[0], $linecolor[1], $linecolor[2]);
            $text = imagecolorallocate($im, $textcolor[0], $textcolor[1], $textcolor[2]);
            // Fill with background color
            imagefill($im, $cx, $cy, $back);
            // Draw internal space of chart
            imagerectangle($im, $chart_left, $chart_top, $chart_right, $chart_bottom, $line);
            imagefill($im, $cx, $cy, $fill);
            // Draw  horizontal grid lines
            for($i = $chart_bottom - $scale_y; $i > $chart_top; $i -= $scale_y) {
                imageline($im, $chart_left, $i, $chart_right, $i, $grid);
            }
            // Draw vertical grid lines
            for($i = $chart_left + $scale_x; $i < $chart_right; $i += $scale_x) {
                imageline($im, $i, $chart_bottom, $i, $chart_top, $grid);
            }
            // Draw dots and/or write values
            for($i = 0, $j = $chart_left + $scale_x; $i < $count && $j <= $chart_right; $i++, $j += $scale_x) {
                $cy = $chart_bottom;
                $y = $min;
                while($y < $values[$keys[$i]]) {
                    $y++;
                    $cy -= $scale_y / $scale;
                }
                imagefilledarc($im, $j, $cy, $scale, $scale, 0, 360, $dots, IMG_ARC_PIE);
                imagearc($im, $j, $cy, $scale, $scale, 0, 360, $line);
                if($showvalues) {
                    $box = imagettfbbox($fontsize, 0, $font_bold, $values[$keys[$i]]);
                    imagettftext($im, $fontsize, 0, $j - $box[4] / 2, $cy - $box[5] / 2, $font, $font_bold, $values[$keys[$i]]);
                }
            }
            // Write X-axis labels
            for($i = 0, $j = $chart_left + $scale_x; $i < $count && $j <= $chart_right; $i++, $j += $scale_x) {
                $box = imagettfbbox($fontsize, 0, $font_regular, $keys[$i]);
                imagettftext($im, $fontsize, 0, $j - $box[4] / 2, $chart_bottom + 15, $font, $font_regular, $keys[$i]);
            }
            // Write Y-axis labels
            for($i = $min, $j = $chart_bottom; $i <= $max, $j >= $chart_top; $i += $scale, $j -= $scale_y) {
                $box = imagettfbbox($fontsize, 0, $font_regular, $i);
                imagettftext($im, $fontsize, 0, $chart_left - $box[4] - 15, $j - $box[5] / 2, $font, $font_regular, $i);
            }
            // Write title
            $box = imagettfbbox($fontsize * 2, 0, $font_bold, $title);
            imagettftext($im, $fontsize * 2, 0, ($width - $box[4]) / 2, $chart_bottom - ($box[5] / 2) + ($height - $chart_bottom) / 2, $text, $font_bold, $title);
            // Output the chart image
            if(!imagepng($im, $filename, 9)) {
                $result = false;
            }
            imagedestroy($im);
        }
        return $result;
    }
?>

مثالی از کاربرد:

<!doctype html>
<html>
<head>
<title>Chart DEMO</title>
<meta charset="utf-8"/>
</head>
<body>
<?php
    require_once 'chart.php';
    $title = 'My Chart';
    $values = array('ASP' => -25, 'JSP' => 15, 'ASP.NET' => 50, 'PHP' => 100);
    $filename = 'MyChart.png';
    if(chart($title, $values, $filename, NULL, NULL, -50, 125, 25, true, 10)) {
        echo '<img border="10px" src="'.$filename.'"/><br/>'.PHP_EOL;
    }
?>
</body>
</html>


نمونه خروجی ضمیمه شده.
من پیشنهادم اینه که دوستان واسه رسم چارت های بیشتر و متنوع تر از کتابخونه pchart استفاده کنن: http://www.pchart.net/

ولی جدیدا به این نتیجه رسیدم که چون این کتابخونه ها میان و چارت ها و نمودارها رو توی عکس ترسیم میکنن و شما باید عکس به کاربر نشون بدین خیلی نتیجه نهایی خوشگل نمیشه و یکجوری میشه خط ها و شکل ها! همچین رنگ و لعاب و سایز خیلی قشنگی نداره!
سعی کنید همون داده هایی رو که قرار بود بدین به کتابخونه در php تا نمودارش رو توی عکس ترسیم کنه، منتقل کنید به سمت کاربر و با کتابخونه های جاوا اسکریپتی چارت رو ترسیم کنید، اینجوری خیلی زیباتر میشه و از اون حالت عکس بی روح در میاد و نمودارها با خود پس زمینه قالبتون هماهنگ میشه و به صورت یک عکس جدا از اون نیست و در نهایت خیلی هم زیباتر میشه. یک مزیت دیگه ای هم که داره اینه که فشار رو از سمت سرور کم میکنید و به گردن کلاینت میندازید که خیلی بهتره.
گاهی اوقات تولید نمودار در سمت سرور لازم میشه. مثلاً جاهایی که امنیت مهمه و نمیخواین نمودارها سمت کلاینت دستکاری بشه یا کلاً هر دلیل دیگه که نیاز به نگهداری نمودارها سمت سرور داشته باشه، وجود اینجور اسکریپتها رو سودمند میکنه. بهرصورت این ویژگی PHP یعنی کار با تصاویر و تولید اونها بصورت On-the-fly قابلیت سودمندی هست که یکی از کاربردهاش رو توی این تکه کد، معرفی کردم.
ار پکیج و کلاس های http://jpgraph.net/ هم می تونید استفاده کنید .

البته از این دسته کلاس ها بسیار زیاد هستند اما همونطور که اشاره شد خروجی آنها به صورت image است که یه خورده تو ذوق کاربر میزنه .