首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP GD 繪製 3D 餅圖完整程式碼教學

     編輯:PHP 綜合知識

功能特色

  • 支援多資料系列、自動計算百分比
  • 3D 立體效果 (側面、頂面陰影)
  • 中文標籤支援 (TrueType 字體)
  • 圖例色塊、數值、百分比顯示
  • 輸出 PNG 檔案、可直接 <img src="pie.php"> 嵌入

完整程式碼 (pie3d.php)

>16)&0xFF, ($hex>>8)&0xFF, $hex&0xFF];
}
function darker($rgb) { return [$rgb[0]/2, $rgb[1]/2, $rgb[2]/2]; }
function ellipsePoint($a, $b, $deg) {
    $rad = deg2rad($deg);
    return [round($a*cos($rad)), round($b*sin($rad))];
}

// 建立畫布
$n = count($data);
$sum = array_sum($data);
$a = 250; $b = 120; // 橢圓長/短軸
$cx = $a + 10; $cy = $b + 10 + PIE_3D_HEIGHT;
$w = $a*2 + 20;
$h = $b*2 + 20 + PIE_3D_HEIGHT + ($n * 18);
$img = imagecreatetruecolor($w, $h);

// 背景白
$white = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $white);

// 分配顏色
$colorIdx = [];
foreach ($colors as $c) {
    $rgb = hexToRgb($c);
    $colorIdx[] = imagecolorallocate($img, ...$rgb);
}
$black = imagecolorallocate($img, 0, 0, 0);

// 繪製扇區 (從 0 度開始)
$startDeg = 0;
$legendY = $b*2 + 20 + PIE_3D_HEIGHT + 10;

for ($i = 0; $i < $n; $i++) {
    $endDeg = $startDeg + ($data[$i] / $sum) * 360;
    $clr = $colorIdx[$i];
    $darkClr = imagecolorallocate($img, ...darker(hexToRgb($colors[$i])));
    
    // 3D 側面 (0-180 度可見)
    if ($startDeg < 180) {
        $visibleEnd = min($endDeg, 180);
        $p1 = ellipsePoint($a, $b, $startDeg);
        $p2 = ellipsePoint($a, $b, $visibleEnd);
        // 左側邊
        imageline($img, $cx+$p1[0], $cy+$p1[1], $cx+$p1[0], $cy+$p1[1]+PIE_3D_HEIGHT, $darkClr);
        // 右側邊
        imageline($img, $cx+$p2[0], $cy+$p2[1], $cx+$p2[0], $cy+$p2[1]+PIE_3D_HEIGHT, $darkClr);
        // 底部弧
        for ($d = $startDeg; $d < $visibleEnd; $d += ANGLE_STEP) {
            $pt = ellipsePoint($a, $b, $d);
            $ptNext = ellipsePoint($a, $b, min($d+ANGLE_STEP, $visibleEnd));
            imageline($img, $cx+$pt[0], $cy+$pt[1]+PIE_3D_HEIGHT, $cx+$ptNext[0], $cy+$ptNext[1]+PIE_3D_HEIGHT, $darkClr);
        }
        // 填充側面 (簡易:中點填充)
        $mid = ellipsePoint($a, $b, ($startDeg+$visibleEnd)/2);
        imagefill($img, $cx+$mid[0], $cy+$mid[1]+PIE_3D_HEIGHT/2, $darkClr);
    }
    
    // 頂面扇區
    imageline($img, $cx, $cy, $cx+$p1[0], $cy+$p1[1], $clr);
    for ($d = $startDeg; $d < $endDeg; $d += ANGLE_STEP) {
        $pt = ellipsePoint($a, $b, $d);
        $ptNext = ellipsePoint($a, $b, min($d+ANGLE_STEP, $endDeg));
        imageline($img, $cx+$pt[0], $cy+$pt[1], $cx+$ptNext[0], $cy+$ptNext[1], $clr);
    }
    imageline($img, $cx, $cy, $cx+$p2[0], $cy+$p2[1], $clr);
    // 填充頂面
    $midTop = ellipsePoint($a/2, $b/2, ($startDeg+$endDeg)/2);
    imagefill($img, $cx+$midTop[0], $cy+$midTop[1], $clr);
    
    // 圖例
    $boxX = 10; $boxY = $legendY + $i * 18;
    imagefilledrectangle($img, $boxX, $boxY, $boxX+12, $boxY+12, $clr);
    imagerectangle($img, $boxX, $boxY, $boxX+12, $boxY+12, $black);
    // 中文需 TrueType 字體
    $font = __DIR__ . '/simsun.ttc'; // 請自備字體檔
    if (file_exists($font)) {
        imagettftext($img, 12, 0, $boxX+18, $boxY+12, $black, $font,
            "{$labels[$i]}: {$data[$i]} (" . round($data[$i]/$sum*10000)/100 . "%)");
    } else {
        imagestring($img, 3, $boxX+18, $boxY+2, $labels[$i], $black);
    }
    
    $startDeg = $endDeg;
}

// 輸出
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);

使用方式

<img src="pie3d.php" alt="3D 餅圖">
// 或帶參數
<img src="pie3d.php?data=30,20,50&labels=A,B,C">

現代替代方案建議

  • Chart.js / ApexCharts / ECharts:前端 JS 圖表庫、互動、動態、響應式、無伺服端負擔
  • QuickChart.io:API 產生圖表圖片、URL 參數配置
  • PHP 圖表庫:pChart、PHPChart、SVGGraph (輸出 SVG、可縮放)
  • 大數據視覺化:Apache Superset、Metabase、Grafana

效能優化提示

  • 啟用 OPcache、避免重複計算
  • 靜態圖表預先產生快取
  • 大量請求考慮前端渲染或 CDN 快取
  • TrueType 字體載入開銷大,建議快取字體資源
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved