我正在尝试创建自己的折线图控件。
我已经创建了将数据(格式:日期 - 值)转换为坐标的逻辑,现在我只需要在视图中显示这些行。
以下是我的示例数据:
我的控件上有一个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
答案 0 :(得分:0)
如果你想在UIVIew上绘制一些东西,你必须将它子类化并在内部绘制你想要的东西
-(void)drawRect:(CGRect)rect
方法。如果该循环超出了drawRect:
,那将无效。
·H
#import <UIKit/UIKit.h>
@interface aView : UIView
@end
的.m
#import "aView.h"
@implementation aView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Sample Rectangle Drawing
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(23, 50, 24, 7)];
[UIColor.grayColor setFill];
[rectanglePath fill];
// Sample Oval Drawing
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(24.5, 65.5, 21, 21)];
[UIColor.blackColor setStroke];
ovalPath.lineWidth = 1;
[ovalPath stroke];
// Sample Horizontal Bezier Drawing
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(23.5, 37.5)];
[bezierPath addCurveToPoint: CGPointMake(45.5, 37.5) controlPoint1: CGPointMake(45.52, 37.5) controlPoint2: CGPointMake(45.5, 37.5)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
// Sample Vertical Bezier Drawing
UIBezierPath* bezier2Path = UIBezierPath.bezierPath;
[bezier2Path moveToPoint: CGPointMake(67.5, 36.5)];
[bezier2Path addCurveToPoint: CGPointMake(67.5, 59.5) controlPoint1: CGPointMake(67.5, 59.52) controlPoint2: CGPointMake(67.5, 59.5)];
[UIColor.blackColor setStroke];
bezier2Path.lineWidth = 1;
[bezier2Path stroke];
//// Drawing Text With Attribute
CGRect textRect = CGRectMake(0, 0, 50, 30);
NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
textStyle.alignment = NSTextAlignmentCenter;
NSDictionary* textFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica" size: 12], NSForegroundColorAttributeName: UIColor.blackColor, NSParagraphStyleAttributeName: textStyle};
[@"Hello, World!" drawInRect: textRect withAttributes: textFontAttributes];
}
@end
答案 1 :(得分:0)
LinearInterpView是UIView的子类,使用此类绘制线
#import "LinearInterpView.h"
@implementation LinearInterpView
{
UIBezierPath *path;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:NO];
[self setBackgroundColor:[UIColor clearColor]];
path = [UIBezierPath bezierPath];
[path setLineWidth:1.];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[[UIColor blackColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p];
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
@end