GDで階層のある円グラフを立体で作成する方法

GDで階層のある円グラフの作成する。

  • 小項目のグラフを書き込むために再帰関数を使用する。
  • 影の部分はY座標を変えて黒の円を書く。
  • 立体部分は円の高さを少しずつ変えながらループして線で書く。

まずは、データを配列で作成

// データ
    $data = array(
                    array(
                        75,
                        "税収",
                        array(
                            array(
                                50,
                                "社会保障",
                                "",
                            ),
                            array(
                                25,
                                "防衛",
                                array(
                                    array(
                                        20,
                                        "陸軍",
                                        array(
                                            array(5,"戦車",""),
                                            array(5,"ロケット",""),
                                            array(8,"歩兵",""),
                                            array(2,"補給",""),
                                        ),
                                    ),
                                    array(
                                        5,
                                        "海軍",
                                        "",
                                    ),
                                   
                                ),
                            ),
                        )
                    ),
                    array(
                        25,
                        "国債費",
                        "",
                    ),
            );

次に関数を作成する

function circle(&$img_parts,$child_data,$child_start,$cut,&$kaisou){
    ++$kaisou;
    if(is_array($child_data)){
        $start = $child_start;
        $end = $start;
       
        $cnt = count($child_data);
        for ($i = 0; $i < $cnt; $i++) {
            $start = $end;
            //if ($data2[$j][0] == 0) { break; }
            $end += (int)(($child_data[$i][0] / $img_parts["sum"]) * 360);
            if ($end >= 360) {
                $end -= 360;
            }
           
            // 0から180の間に被ってたときのみ
            // 立体的にするための描画
            if (($kaisou == 1) &&(($start > 0 && $start < 180) || ($end > 0 && $end < 180) || ($start >= 270 && $end >= 180))) {
                for ($j = 0; $j <= 10; $j++) {
                    imagearc($img_parts["img"], $img_parts["cx"], $img_parts["cy"]+$j,$img_parts["width"], $img_parts["height"], $start, $end,  $img_parts["color3D{$kaisou}"][$i]);
                   
                }
            }

           
            imagefilledarc($img_parts["img"], $img_parts["cx"], $img_parts["cy"],$img_parts["width"]-$cut, $img_parts["height"]-$cut, $start, $end, $img_parts["color{$kaisou}"][$i], IMG_ARC_PIE);
       
            if(!empty($child_data[$i][2])){
               
                circle(&$img_parts,$child_data[$i][2],$start,$cut+50,$kaisou);
                –$kaisou;
            }
           
           
        }
       
        return;
    }
}

パーツを作って、いろいろ渡す

時計で言うと3時のところが角度0となるので、スタートを角度270からにする。

$start = 270;
$end = 270;

割合を出すために、数値の合計を出しておく。

$sum = 0;
    for ($i = 0; $i < $count; $i++) {
        $sum += $data[$i][0];
 }

その他高さや色などを設定する。

    $img_parts = array(
                    "cx"      => 150,
                    "cy"      => 150,
                    "width"   => 250,
                    "height"  => 250,
                    "sum"  => $sum,

                    );

$color1[0]        = imagecolorallocate($image, 0, 255, 255);

$img_parts["color1"] = $color1;

~省略

// 立体感を出すための黒いちょっと大きいぐらいの半円
    imagefilledarc($image, $cx, $cy + 15, $width, $height, -30, 210, $color, IMG_ARC_PIE);

ここで作った画像にクリッカブルマップを設定して、クリックすると項目の内容などを表示できるようにした。

不備があったら質問してください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です