[PHP]レーダーチャート(クモの巣グラフ)をGDで描画する

以前の記事で座標の回転を行う関数を作ったので、
それを利用する形で本格的なレーダーチャートを作ります。

rader

<?php
//値
$values = array(6,7,8,10,7,8);

//ラベル
$labels = array("red", "green", "blue", "yellow", "black", "white");

$max         = 10;    //上限
$step        = 2;     //目盛の間隔
$margin	     = 80;    //グラフの余白
$text_margin = 20;    //ラベルの余白
$size        = 240;   //サイズ(正方形)

//フォント
$font = "migmix-1p-regular.ttf";
$font_size = 10;

//画像
$image = imagecreatetruecolor( $size + $margin , $size + $margin);
imageantialias($image, true);

//色
$bg   = imagecolorallocate($image, 10, 10, 10);    // 背景
$line = imagecolorallocate($image, 255, 255, 255); // チャートの線
$grid = imagecolorallocate($image, 50, 50, 50);	   // グリッドの色
$font_color = imagecolorallocate($image, 255, 160, 200);

$center_x = round(($size + $margin) / 2);
$center_y = round(($size + $margin) / 2);
$count = count($values);
$div = round(360 / $count);
$length = round($size / 2);

// 背景の描画
imagefill($image, 0, 0, $bg);
for($i = 1;$i<=$max;$i++){	
	if($i%$step != 0) continue;
	$points = array();
	for($j=0;$j<$count;$j++){
		list($x, $y) = point_rotate($length * ($i / $max), $div * $j - 90);

		$point = array($x + $center_x, $y + $center_y);
		imageline($image, $center_x, $center_y, $point[0], $point[1], $grid);
		$points = array_merge($points, $point);
	}
	imagepolygon($image, $points, $count, $grid);
}


// 文字の描画
for($i = 0;$i<$count;$i++){
	$box = imagettfbbox($font_size, 0, $font, $labels[$i]);
	$text_width = $box[2] - $box[6];
	$text_height = $box[3] - $box[7];

	list($x, $y) = point_rotate($length + $text_margin, $div * $i - 90);
	
	$text_x = (-1 * $text_width / 2) + $center_x + $x;
	$text_y = ($text_height / 2) + $center_y + $y;
	imagettftext($image, $font_size, 0, $text_x, $text_y, $font_color, $font, $labels[$i]);
}

for($i=0;$i<=$max;$i=$i+$step){
	$box = imagettfbbox($font_size, 0, $font, $i);
	$text_width = $box[2] - $box[6];
	$text_height = $box[3] - $box[7];
	
	$text_x = (-1 * $text_width) + $center_x - $font_size;
	$text_y = ($text_height / 2) + $center_y - ($length * ($i / $max));
	imagettftext($image, $font_size, 0, $text_x, $text_y, $grid, $font, $i);
}

// グラフの描画
$points = array();
for($i=0;$i<$count;$i++){
	$value = $length * $values[$i] / $max;
	list($x, $y) = point_rotate($value, $div * $i - 90);
	$point = array($x + $center_x, $y + $center_y);
	$points = array_merge($points, $point);
	
}
imagepolygon($image, $points, $count, $line);

// 画像の出力
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);

function point_rotate($length, $angle){
  $angle = deg2rad($angle);
  $x = round($length * cos($angle));
  $y = round($length * sin($angle));
  return array($x, $y);
}
?>

このプログラムを利用するには同じフォルダにフォントファイルをアップロードしておく必要があります。
今回はフリーフォント MigMix を利用しました。

MigMix フォント
http://mix-mplus-ipa.sourceforge.jp/

このプログラムでは項目数に応じた多角形のレーダーチャートを生成できます。
頂点には項目名が表示され、垂直の軸にはメモリが表示されます。
目盛の間隔(step)を調整することで、10 ごとに目盛線を入れる等の設定ができます。

項目名が長くなる場合はテキストの余白($text_margin)を大きめにとって下さい。

[PHP]円グラフを表示する(GD)

piegraph

円グラフを PHP で作るには GD に含まれる imagefilledarc() を使うのが便利です。
この関数は塗りつぶした楕円弧を描くためのものです

<?php
//値
$values = array(30, 40, 60, 80, 20);

//グラフに使う色
$colorset = array(
	'ff3b3b', 'bc3bff', '44aeff', 'aeff3b', 'ffa53b'
);

$width	 = 240;
$height	 = 240;

$cx = round( $width / 2 );
$cy = round( $height / 2 );

$image = imagecreatetruecolor($width, $height);

//背景
$bg		 = imagecolorallocate( $image, 255, 255, 255 );
imagefill($image, 0, 0, $bg);

list($red, $green, $blue) = parse_color($colorset[0]);

rsort($values);
$scale = 360 / array_sum($values);
$count = count($values);

$start = -90;
$end = $start;

foreach($values as $key => $value){
	list($red, $green, $blue) = parse_color( current($colorset) );
	$start = $end;
	$end = ($key === $count - 1) ? 270 : $end = $value * $scale + $start;
	$color = imagecolorallocate($image, $red, $green, $blue);
	imagefilledarc($image, $cx, $cy, $width, $height, $start, $end, $color, IMG_ARC_PIE);
	$res = next($colorset);
	if($res === false) reset($colorset);
}

// 画像を出力します
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);

function parse_color($rgb){
	$res = str_split($rgb, 2);
	$red	 = intval($res[0], 16);
	$green	 = intval($res[1], 16);
	$blue	 = intval($res[2], 16);
	return array( $red, $green, $blue );
}

配列の数値を大きいものから順に並び替え、360 度で表せるように倍率を調整しています。
丸め誤差によりぴったりと円が閉じないことがあるので最後の値の時は確実に閉じるように処理を加えてあります。

この関数の 0 度は 3 時方向からスタートするので、12 時方向からスタートさせるために -90 度させています。

グラフに使う色は 16 進数で指定できるようにしました。直接 RGB の数値をそれぞれ入力させてもいいのですが馴染みやすいのでこの表示を使っています。
カラーセットで用意した色数よりも多い値が与えられても、繰り返し使用するので色が不足することはありませんが、数によっては開始の色と最後の値の色が同じになってしまうので、値が奇数個の時と偶数個の時でカラーセットの数を調整する仕組みをつけたほうがいいと思います。