我正在尝试创建自己的折线图控件。
我已经创建了将数据(格式:日期 - 值)转换为坐标的逻辑,现在我只需要在视图中显示线条。
这是我的示例数据:
我的控件上有一个 UIView,出口是:
@property (weak, nonatomic) IBOutlet UIView *iboChartsFieldView;
所以这是我画线的功能:
- (void)drawLine:(ChartPoint*)start endPoint:(ChartPoint *) end
{
UIGraphicsBeginImageContext(self.iboChartsFieldView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
float num[] = {6.0, 6.0};
CGContextSetLineDash(context, 0.0, num, 2);
CGRect rectangle;
float x, y, width, height;
x=start.xCord;
width = end.xCord - start.xCord;
if(start.yCord < end.yCord) {
y = start.yCord;
height = end.yCord - start.yCord;
}
else {
y = start.yCord;
height = start.yCord - end.yCord;
}
rectangle = CGRectMake(x, y, width, height);
CGContextAddRect(context, rectangle);
CGContextStrokePath(context);
}
这是我如何使用它:
for (int i=1; i<sortedPointArray.count; i++) {
ChartPoint *startPoint = [sortedPointArray objectAtIndex:i-1];
ChartPoint *endPoint = [sortedPointArray objectAtIndex:i];
[self drawLine:startPoint endPoint:endPoint];
}
我的 iboChartsFieldView 中没有显示任何内容。我究竟做错了什么?
我的完整控制源代码:
#import "LineChartsControl.h"
#import "ChartPoint.h"
@interface LineChartsControl ()
@property (weak, nonatomic) IBOutlet UIView *iboChartsFieldView;
@property (weak, nonatomic) IBOutlet UILabel *iboFirstTimeStampLabel;
@end
NSMutableDictionary *chartData;
NSMutableArray *pointsArray;
NSArray *sortedPointArray;
float xAxisStepInPixels;
float yAxisStepInPixels;
NSDate *xAxisMinValue;
float yAxisMinValue;
NSDate *xAxisMaxValue;
float yAxisMaxValue;
@implementation LineChartsControl
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//[self getChartData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)getChartData{
//Here must be code to retrieve previous data for case
chartData = [[NSMutableDictionary alloc] init];
[chartData setObject:@"4" forKey:@"2014-07-17T10:32:00+03:00"];
[chartData setObject:@"1" forKey:@"2014-07-17T10:38:00+03:00"];
[chartData setObject:@"2" forKey:@"2014-07-17T10:39:00+03:00"];
[chartData setObject:@"5" forKey:@"2014-07-17T10:40:00+03:00"];
[chartData setObject:@"3" forKey:@"2014-07-17T10:41:00+03:00"];
[chartData setObject:@"4" forKey:@"2014-07-17T10:42:00+03:00"];
[chartData setObject:@"4" forKey:@"2014-07-17T10:43:00+03:00"];
if(chartData.count>1)
{
[self calculateXAxisLength];
[self calculateYAxisLength];
[self generatePointsArray];
[self refreshChart];
NSLog(@"%f",xAxisStepInPixels);
NSLog(@"%f",yAxisStepInPixels);
}
}
-(void)calculateXAxisLength
{
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *xMin = [timeFormat dateFromString:@"3000-07-17T10:42:00+03:00"];
NSDate *xMax = [timeFormat dateFromString:@"1000-07-17T10:42:00+03:00"];
for (NSString *xAxis in [chartData allKeys]) {
NSDate *date = [timeFormat dateFromString:xAxis];
if([date timeIntervalSinceDate:xMax] > 0)
{
xMax = date;
}
if([date timeIntervalSinceDate:xMin] < 0)
{
xMin = date;
}
}
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSSecondCalendarUnit
fromDate:xMin
toDate:xMax
options:0];
xAxisMinValue = xMin;
xAxisMaxValue = xMax;
xAxisStepInPixels = self.iboChartsFieldView.frame.size.width/[components second];
}
-(void)calculateYAxisLength
{
float xMin = 99999999;
float xMax = -99999999;
for (NSString *xAxis in [chartData allKeys]) {
float value = [chartData[xAxis] floatValue];
if(value>xMax)
{
xMax = value;
}
if(value<xMin)
{
xMin = value;
}
}
yAxisMinValue=xMin;
yAxisMaxValue=xMax;
yAxisStepInPixels = self.iboChartsFieldView.frame.size.height/(xMax-xMin);
}
-(void)generatePointsArray{
pointsArray = [[NSMutableArray alloc] init];
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
for (NSString *xAxis in [chartData allKeys]) {
NSDate *date = [timeFormat dateFromString:xAxis];
ChartPoint *chartPoint = [[ChartPoint alloc] init];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSSecondCalendarUnit
fromDate:date
toDate:xAxisMaxValue
options:0];
chartPoint.xCord = [components second]*xAxisStepInPixels;
float value = [chartData[xAxis] floatValue];
chartPoint.yCord = (value - yAxisMinValue)*yAxisStepInPixels;
[pointsArray addObject:chartPoint];
}
NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"xCord" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:firstDescriptor, nil];
sortedPointArray = [[NSArray alloc]init];
sortedPointArray = [pointsArray sortedArrayUsingDescriptors:sortDescriptors];
}
- (void)drawLine:(ChartPoint*)start endPoint:(ChartPoint *) end
{
UIGraphicsBeginImageContext(self.iboChartsFieldView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
float num[] = {6.0, 6.0};
CGContextSetLineDash(context, 0.0, num, 2);
CGRect rectangle;
float x, y, width, height;
x=start.xCord;
width = end.xCord - start.xCord;
if(start.yCord < end.yCord) {
y = start.yCord;
height = end.yCord - start.yCord;
}
else {
y = start.yCord;
height = start.yCord - end.yCord;
}
rectangle = CGRectMake(x, y, width, height);
CGContextAddRect(context, rectangle);
CGContextStrokePath(context);
}
-(void)refreshChart{
if(chartData.count!=sortedPointArray.count)
{
[self calculateXAxisLength];
[self calculateYAxisLength];
[self generatePointsArray];
}
for (int i=1; i<sortedPointArray.count; i++) {
ChartPoint *startPoint = [sortedPointArray objectAtIndex:i-1];
ChartPoint *endPoint = [sortedPointArray objectAtIndex:i];
[self drawLine:startPoint endPoint:endPoint];
}
}
@end