说实话,OC代码写着真的很别扭,速度明显慢N倍.
下面是一个简单的line chart,虽然很难看,但是好歹照虎画猫也能弄个模子出来...
#define AXIS_Y_ITEM_COUNT 5
#define AXIS_X_ITEM_COUNT 5
NSMutableArray* radom_data() {
srand((unsigned)time(NULL));
float base = 30;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++) {
NSLog(@"%f", (rand() % 1000) / 100.f + base);
[array addObject:[NSNumber numberWithFloat:((rand() % 1000) / 100.f + base)]];
}
return array;
}
float _max(NSArray *data) {
float max = [[data objectAtIndex:0] floatValue];
for(NSNumber* num in data) {
max = [num floatValue] > max ? [num floatValue] : max;
}
return max;
}
float _min(NSArray *data) {
float min = [[data objectAtIndex:0] floatValue];
for(NSNumber* num in data) {
min = [num floatValue] < min ? [num floatValue] : min;
}
return min;
}
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
viewFrame = frame;
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(@"######################## %f %f", viewFrame.size.width, viewFrame.size.height);
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMinimumFractionDigits:2];
[numberFormatter setMaximumFractionDigits:2];
NSMutableArray* data = radom_data();
float max = _max(data);
float min = _min(data);
float offsetWidth = 80.0f; // 50 * 2 + 10 * 2
float offsetHeight = 60.0f; // 20 * 2 + 10 * 2
float stepY = (max - min) / AXIS_Y_ITEM_COUNT;
float axisY_step = (viewFrame.size.height - offsetHeight) / (max - min);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
for (int i = 0; i < AXIS_Y_ITEM_COUNT + 1; i++) {
CGFloat lineDash[2];
lineDash[0] = 10.0f;
lineDash[1] = 15.0f;
CGContextSetLineDash(context, 0.0f, lineDash, 2);
CGContextSetLineWidth(context, 0.6f);
CGPoint sPoint = CGPointMake(offsetWidth / 2, viewFrame.size.height - (offsetHeight / 2) - i * stepY * axisY_step);
CGPoint ePoint = CGPointMake(viewFrame.size.width - offsetWidth / 2, viewFrame.size.height - (offsetHeight / 2) - i * stepY * axisY_step);
CGContextMoveToPoint(context, sPoint.x, sPoint.y);
CGContextAddLineToPoint(context, ePoint.x, ePoint.y);
CGContextClosePath(context);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextStrokePath(context);
UIFont *axisFont = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
NSNumber *axisValue = [NSNumber numberWithFloat:(min + i * stepY)];
CGRect axisRect = CGRectMake(0.0f, sPoint.y - axisFont.capHeight, 50.0f, 20.0f);
//CGRect axisRect = CGRectMake(0.0f, sPoint.y, 50.0f, 20.0f);
[[UIColor redColor] set];
NSLog(@"%@", [numberFormatter stringForObjectValue:axisFont]);
[[numberFormatter stringForObjectValue:axisValue] drawInRect:axisRect withFont:axisFont
lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
}
float stepX = 100 / AXIS_X_ITEM_COUNT;
float axisX_step = (viewFrame.size.width - offsetWidth) / 100;
CGContextSetLineDash(context, 0.0f, NULL, 0);
for(int i = 0; i < AXIS_X_ITEM_COUNT + 1; i++) {
CGPoint sPoint = CGPointMake(offsetWidth / 2 + i * stepX * axisX_step, viewFrame.size.height - offsetHeight / 2);
CGContextMoveToPoint(context, sPoint.x, viewFrame.size.height - offsetHeight / 2);
CGContextAddLineToPoint(context, sPoint.x, viewFrame.size.height - offsetHeight / 2 + 10);
CGContextClosePath(context);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextStrokePath(context);
CGRect axisRect = CGRectMake(sPoint.x - 50 / 2, viewFrame.size.height - 20, 50.0f, 20.0f);
UIFont *axisFont = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
NSNumber *axisValue = [NSNumber numberWithInt:(i * stepX)];
NSLog(@"%f %f %@", axisRect.origin.x, axisRect.origin.y, [axisValue stringValue]);
[[UIColor yellowColor] set];
[[axisValue stringValue] drawInRect:axisRect withFont:axisFont
lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter];
}
/*
CGContextSetLineDash(context, 0.0f, NULL, 0);
CGContextMoveToPoint(context, offsetWidth / 2, 0.0);
CGContextAddLineToPoint(context, offsetWidth / 2, viewFrame.size.height - offsetHeight / 2 + 10);
CGContextClosePath(context);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextStrokePath(context);
*/
int _x = 0;
for (NSNumber *number in data) {
float value = [number floatValue];
CGPoint point = CGPointMake(_x++ * axisX_step + offsetWidth / 2, viewFrame.size.height - offsetHeight / 2 - (value - min) * axisY_step);
if(_x == 1) {
CGContextMoveToPoint(context, point.x, point.y);
}
else {
CGContextAddLineToPoint(context, point.x, point.y);
}
}
//CGContextSetLineCap(context, kCGLineCapRound);
//CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetStrokeColorWithColor(context, [UIColor cyanColor].CGColor);
CGContextStrokePath(context);
}
- (void)dealloc {
[super dealloc];
}
@synthesize viewFrame;