成績表などで複数のカテゴリーを一目で比較する際によく使うグラフ「レーダーチャート(クモの巣グラフ)」を表示するiPhoneアプリの作成方法を書いてみます。今回は5つのカテゴリーに、1から5までのランクをつける五角形にしてみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
グラフの基準点として、カテゴリ×ランクの計25個のCGPointをループの中で計算しておき、赤い線で結ぶところをintで5個用意、初期値は{3, 3, 3, 3, 3}とオール3にしました。グラフの増減は、UISegmentControllerの値とランクの値をTargetActionの呼び出しの中で連動させています。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
CGPoint points[25];
int level[5];
UIView *chart;
CAShapeLayer *redline;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor darkGrayColor];
[self setupPoints];
[self setChartFrame];
[self createBars];
[self showGraph];
}
– (void)setupPoints
{
for (int i=0; i<25; i++) {
float angle = (i/5) * (M_PI / 2.5) – M_PI/2.0;
float length = (i % 5 + 1) * 30;
points[i] = CGPointMake(length * cos(angle) + 160, length * sin(angle) + 160);
}
for(int i=0; i<5; i++) {
level[i] = 3;
}
}
– (void)setChartFrame
{
chart = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 310)];
chart.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
chart.layer.borderColor = [UIColor darkGrayColor].CGColor;
chart.layer.borderWidth = 10;
[self.view addSubview:chart];
for (int i=0; i<25; i++) {
UIView *mark = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 3, 3)];
mark.layer.cornerRadius = 1.5;
mark.backgroundColor = [UIColor darkGrayColor];
mark.center = points[i];
[chart addSubview:mark];
}
UIBezierPath *outpath = [UIBezierPath bezierPath];
for (int i=0; i<5; i++) {
[outpath moveToPoint:points[i]];
[outpath addLineToPoint:points[i+5]];
[outpath addLineToPoint:points[i+10]];
[outpath addLineToPoint:points[i+15]];
[outpath addLineToPoint:points[i+20]];
[outpath addLineToPoint:points[i]];
}
for (int i=0; i<5; i++) {
[outpath moveToPoint:CGPointMake(160, 160)];
[outpath addLineToPoint:points[i * 5 + 4]];
}
CAShapeLayer *outline = [[CAShapeLayer alloc] init];
outline.fillColor = [UIColor clearColor].CGColor;
outline.strokeColor = [UIColor darkGrayColor].CGColor;
outline.lineWidth = 1;
outline.path = outpath.CGPath;
[chart.layer addSublayer:outline];
}
– (void)showGraph
{
if(!redline) {
redline = [[CAShapeLayer alloc] init];
redline.fillColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.3].CGColor;
redline.strokeColor = [UIColor redColor].CGColor;
redline.lineWidth = 6;
[chart.layer addSublayer:redline];
}
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:points[level[0] – 1]];
[path addLineToPoint:points[level[1] + 4]];
[path addLineToPoint:points[level[2] + 9]];
[path addLineToPoint:points[level[3] + 14]];
[path addLineToPoint:points[level[4] + 19]];
[path addLineToPoint:points[level[0] – 1]];
redline.path = path.CGPath;
}
– (void)createBars
{
for (int i=0; i<5; i++) {
UISegmentedControl *sgc = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@”1″, @”2″, @”3″, @”4″, @”5″, nil]];
sgc.frame = CGRectMake(10, 320 + i * 40, 300, 30);
sgc.segmentedControlStyle = UISegmentedControlStylePlain;
sgc.selectedSegmentIndex = 2;
sgc.tag = i;
[self.view addSubview:sgc];
[sgc addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];
}
}
– (void)change:(UISegmentedControl*)sgc
{
int type = sgc.tag;
level[type] = sgc.selectedSegmentIndex + 1;
[self showGraph];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end