Reputation: 395
I am drawing Donut Chart.I am using CGPath
to draw and after drawing adding it to CAShapeLayer
. First I draw an outer arc and then draw line toward centre, now I want to add arc to my current point.
Screenshot of this is below.
See smaller arc should be at the end of line.
My code,
for (int j = 0; j < numSubject; j++) {
int valueForSubject = [datasource valueOfSubjectAtIndex:j andLevel:i inDonutChartView:self];
endAngle = [self angleInRadianFromSubjectValue:valueForSubject];
DLog(@"Angle - %f",RADIANS_TO_DEGREES(endAngle))
//path
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, prevPoint.x, prevPoint.y, radius, startAngle, endAngle, NO);
CGPoint currentPoint = CGPathGetCurrentPoint(path);
//find angles from start point to center and end point to center
CGFloat angle1 = [self angleFromFirstPoint:prevPoint secondPoint:centerPoint];
CGFloat angle2 = [self angleFromFirstPoint:CGPathGetCurrentPoint(path) secondPoint:centerPoint];
double endX1 = cos(angle1) * LEVEL_WIDTH + prevPoint.x;
double endY1 = sin(angle1) * LEVEL_WIDTH + prevPoint.y;
double endX2 = cos(angle2) * LEVEL_WIDTH + CGPathGetCurrentPoint(path).x;
double endY2 = sin(angle2) * LEVEL_WIDTH + CGPathGetCurrentPoint(path).y;
//first connect current point to end2 point then draw arc and then connect to end1
CGPathAddLineToPoint(path, NULL, endX2, endY2);
//CGPathAddArcToPoint(path, NULL, CGPathGetCurrentPoint(path).x, CGPathGetCurrentPoint(path).y, endX2, endY2, radius - LEVEL_WIDTH);
CGPathAddArc(path, NULL, CGPathGetCurrentPoint(path).x , CGPathGetCurrentPoint(path).y, radius - LEVEL_WIDTH, endAngle, startAngle, YES);
//CGPathAddLineToPoint(path, NULL, endX1, endY1);
//CGPathCloseSubpath(path);
A3DonutChartShapeLayer* arcLayer = [[A3DonutChartShapeLayer alloc]init];
arcLayer.path = path;
//arcLayer.frame = CGPathGetBoundingBox(path);
arcLayer.lineWidth = BORDER_WIDTH;
arcLayer.strokeColor = [UIColor blackColor].CGColor;
arcLayer.fillColor = [UIColor clearColor].CGColor;
[self.layer addSublayer:arcLayer];
Any pointers?
Upvotes: 1
Views: 1200
Reputation: 395
here it is:
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, rect.size.width/2, rect.size.height/2, 100, startAngle, endAngle, NO);
CGPathAddArc(path, NULL, rect.size.width/2, rect.size.height/2, 100-50, endAngle, startAngle, YES);
CGPathCloseSubpath(path);
Upvotes: 1
Reputation: 56625
Paths already do that. Lines, arcs, curves, etc. are all added from the current point. It looks like you are passing the current point for the x and y arguments in CGPathAddArc(...)
but those arguments are used for the center of the arc, not the start.
That said, there is a much better way of doing donut charts. First you do the single arc in te center of the donut then you create a new path by stroking that arc. This allows you to customize the width of the donut very easily. I've described this and broken down the code in great detail in this answer but here is a shorter version of the shape itself.
Create the arc in the center of the donut (orange line in the below image)
CGMutablePathRef arc = CGPathCreateMutable();
CGPathMoveToPoint(arc, NULL,
startPoint.x, startPoint.y);
CGPathAddArc(arc, NULL,
centerPoint.x, centerPoint.y,
radius,
startAngle,
endAngle,
YES);
Create a new path by stroking that path (dotted shape in the image above and filled shape in the image below):
CGFloat lineWidth = 10.0;
CGPathRef strokedArc =
CGPathCreateCopyByStrokingPath(arc, NULL,
lineWidth,
kCGLineCapButt,
kCGLineJoinMiter, // the default
10); // 10 is default miter limit
Upvotes: 0
Reputation: 14118
Option 1: CorePlot API Instead of drawing by self, and taking care of all the scenarios, I would prefer to use: CorePlot
Option 2: Google Chart API
NSString* myurl=@"http://chart.apis.google.com/chart?cht=pc&chd=t:120,45%7c120,60,50,70,60&chs=300x200&chl=%7c%7chelo%7cwrd%7cindia%7cpak%7cban&chco=FFFFFF%7cFFFFFF,e72a28%7ca9d331%7cffce08%7c8a2585%7c184a7d";
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:myurl] cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLResponse* response;
NSError* error;
NSData *imageData=[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
UIImage *myimage = [[UIImage alloc] initWithData:imageData];
Option 3: Nice Tutorial for Core Graphics and ARC drawing
Option 4: Using HTML + CSS + JavaScript
Add a UIWebView and display a local HTML page which will generate dynamic graph according to the values passed to JavaScript
Upvotes: 0