「折れ線グラフ」をiPhoneアプリで書いてみます。データAを青い四角、データBを赤い丸でプロットし、直線で繋いでいきましょう。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
データAとデータB、この二つの折れ線を描いていきます。UIBezierPathとCAShapLayerでグラフの線を作り、表示の際にはアニメーションするようにしています。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
NSArray *dataA;
NSArray *dataB;
BOOL showA;
BOOL showB;
CAShapeLayer *slA;
CAShapeLayer *slB;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
showA = YES;
showB = YES;
[self createDataSheet];
[self drawChart];
[self createLabel];
}
– (void)createDataSheet
{
dataA = @[@1, @2, @3, @4, @5, @6];
dataB = @[@2, @8, @9, @12, @8, @10];
slA = [[CAShapeLayer alloc] init];
slA.fillColor = [UIColor clearColor].CGColor;
slA.strokeColor = [UIColor blueColor].CGColor;
slA.lineWidth = 2;
[self.view.layer addSublayer:slA];
slB = [[CAShapeLayer alloc] init];
slB.fillColor = [UIColor clearColor].CGColor;
slB.strokeColor = [UIColor redColor].CGColor;
slB.lineWidth = 2;
[self.view.layer addSublayer:slB];
}
– (void)drawChart
{
float dx = 90;
float dy = 20;
float x = 50;
float y = 280;
BOOL animA = NO;
BOOL animB = NO;
if (!slA.path) {
animA = YES;
}
if (!slB.path) {
animB = YES;
}
if (showA) {
UIBezierPath *path = [[UIBezierPath alloc] init];
for (int i=0; i<[dataA count]; i++) {
float px = x + dx * i;
float py = y – [[dataA objectAtIndex:i] intValue] * dy;
if (i == 0) {
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(px, py, 10, 10)]];
[path moveToPoint:CGPointMake(px + 5, py + 5)];
} else {
[path addLineToPoint:CGPointMake(px + 5, py + 5)];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(px, py, 10, 10)]];
[path moveToPoint:CGPointMake(px + 5, py + 5)];
}
}
slA.path = path.CGPath;
} else {
slA.path = nil;
}
if (showB) {
UIBezierPath *path = [[UIBezierPath alloc] init];
for (int i=0; i<[dataB count]; i++) {
float px = x + dx * i;
float py = y – [[dataB objectAtIndex:i] intValue] * dy;
if (i == 0) {
[path appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(px, py, 10, 10) cornerRadius:5]];
[path moveToPoint:CGPointMake(px + 5, py + 5)];
} else {
[path addLineToPoint:CGPointMake(px + 5, py + 5)];
[path appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(px, py, 10, 10) cornerRadius:5]];
[path moveToPoint:CGPointMake(px + 5, py + 5)];
} }
slB.path = path.CGPath;
} else {
slB.path = nil;
}
if (animA) {
[self startDraw:slA duration:0.3];
}
if (animB) {
[self startDraw:slB duration:0.3];
}
}
– (void)createLabel
{
UIView *lframe = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 60)];
lframe.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6];
lframe.layer.cornerRadius = 10;
[self.view addSubview:lframe];
UILabel *a = [[UILabel alloc] initWithFrame:CGRectMake(10, 8, 70, 20)];
a.text = @”data A”;
a.textColor = [UIColor whiteColor];
a.backgroundColor = [UIColor colorWithWhite:0 alpha:0.0001];
a.textAlignment = NSTextAlignmentRight;
[lframe addSubview:a];
UIView *markA = [[UIView alloc] initWithFrame:CGRectMake(0, 5, 10, 10)];
markA.backgroundColor = [UIColor blueColor];
[a addSubview:markA];
UILabel *b = [[UILabel alloc] initWithFrame:CGRectMake(10, 33, 70, 20)];
b.text = @”data B”;
b.textColor = [UIColor whiteColor];
b.backgroundColor = [UIColor colorWithWhite:0 alpha:0.0001];
b.textAlignment = NSTextAlignmentRight;
[lframe addSubview:b];
UIView *markB = [[UIView alloc] initWithFrame:CGRectMake(0, 5, 10, 10)];
markB.backgroundColor = [UIColor redColor];
[b addSubview:markB];
NSArray *labels = @[a, b];
for (UILabel *l in labels) {
l.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapLabel:)];
[l addGestureRecognizer:tap];
}
}
– (void)tapLabel:(UITapGestureRecognizer*)gr
{
UILabel *l = (UILabel*)gr.view;
if ([l.text isEqual:@”data A”]) {
showA = !showA;
}
if ([l.text isEqual:@”data B”]) {
showB = !showB;
}
[self drawChart];
}
– (void)startDraw:(CALayer*)l duration:(float)duration
{
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];
a.duration = duration;
a.fromValue = @0;
a.toValue = @1;
[l addAnimation:a forKey:@”strokeEnd”];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end