1

我正在绘制甜甜圈图。我CGPath用来绘制并在绘制后将其添加到CAShapeLayer. 首先我画一个外圆弧,然后向中心画线,现在我想将圆弧添加到我的当前点。

截图如下。

在此处输入图像描述

看到较小的弧线应该在行尾。

我的代码,

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];

任何指针?

4

3 回答 3

1

这里是:

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);
于 2013-09-06T08:45:15.413 回答
0

A note on your actual question

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.


A much better way of doing a donut chart.

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.

Code to do this

Create the arc in the center of the donut (orange line in the below image)

enter image description here

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):

enter image description here

CGFloat lineWidth = 10.0;
CGPathRef strokedArc =
    CGPathCreateCopyByStrokingPath(arc, NULL,
                                   lineWidth,
                                   kCGLineCapButt,
                                   kCGLineJoinMiter, // the default
                                   10); // 10 is default miter limit
于 2013-09-06T09:37:44.653 回答
0

选项 1:CorePlot API 而不是自己绘制,并照顾所有的场景,我更喜欢使用:CorePlot

选项 2:谷歌图表 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];

选项 3:Core Graphics 和 ARC 绘图的好教程

RayWenderlich 教程

选项 4:使用 HTML + CSS + JavaScript

添加一个 UIWebView 并显示一个本地 HTML 页面,该页面将根据传递给 JavaScript 的值生成动态图

于 2013-09-06T06:25:09.470 回答