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);
ここで作った画像にクリッカブルマップを設定して、クリックすると項目の内容などを表示できるようにした。
不備があったら質問してください。