Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView drawing an arc type gauge chart

I have a chart which is in the shape of an gauge which has multiple design elements to it (see attachment). Key parts I'm struggling with is really getting a decent arc shape with dashed lines.

So far I'm not sure if I should be going down Core Graphics route or using something within UIKit, i.e. UIBezierPath.

I've tried this within a class that extend UIView which gives me the dashed lines but the arc itself isn't quite good enough:

class Example: UIView {

    override func drawRect(rect: CGRect) {

        let context = UIGraphicsGetCurrentContext()
        CGContextSetLineWidth(context, 10.0)
        CGContextSetStrokeColorWithColor(context, UIColor.greenColor().CGColor)
        let dashArray:[CGFloat] = [1,10, 0, 0]
        CGContextSetLineDash(context, 2, dashArray, 4)
        CGContextMoveToPoint(context, 10, 200)
        CGContextAddQuadCurveToPoint(context, 0, 0, 100, 200)
        CGContextStrokePath(context)
    }
}

There are then some other ways to get this going using UIBezierPath but I'm not sure how I would go about applying the dashed lines through here...

The main base of getting the arc with dashed lines is my main goal atm - I'm sure once I get this I'll be able to workout the gradient and animation :)

Any help would be appreciated :)

enter image description here

like image 224
sukh Avatar asked May 16 '16 14:05

sukh


1 Answers

What you need is two bezier paths with different dash widths.

You can start from herE:

T0 get the higher dash bezier:

enter image description here

UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];

and to get small dash patterned bezier, you need to reduce the gap between dashes:

enter image description here

UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};   
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];

and now you can put these two bezier path together:

enter image description here

- (void)drawFrame: (CGRect)frame
{

    // Oval Drawing
    UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(frame), 70, 70)];
    [UIColor.redColor setStroke];
    ovalPath.lineWidth = 6;
    CGFloat ovalPattern[] = {2, 1};
    [ovalPath setLineDash: ovalPattern count: 2 phase: 0];
    [ovalPath stroke];


    // Oval 2 Drawing
    UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame) - 0.5, 70, 70)];
    [UIColor.redColor setStroke];
    oval2Path.lineWidth = 13;
    CGFloat oval2Pattern[] = {2, 20};
    [oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
    [oval2Path stroke];
}

Swift:

func drawCanvas1(frame frame: CGRect = CGRect(x: 86, y: 26, width: 70, height: 70)) {
    let context = UIGraphicsGetCurrentContext()

    // Oval Drawing
    let ovalPath = UIBezierPath(ovalInRect: CGRect(x: frame.minX, y: frame.minY, width: 70, height: 70))
    UIColor.redColor().setStroke()
    ovalPath.lineWidth = 6
    CGContextSaveGState(context)
    CGContextSetLineDash(context, 4.5, [0, 1], 2)
    ovalPath.stroke()
    CGContextRestoreGState(context)


    // Oval 2 Drawing
    let oval2Path = UIBezierPath(ovalInRect: CGRect(x: frame.minX + 0.5, y: frame.minY - 0.5, width: 70, height: 70))
    UIColor.redColor().setStroke()
    oval2Path.lineWidth = 13
    CGContextSaveGState(context)
    CGContextSetLineDash(context, 39, [1, 10], 2)
    oval2Path.stroke()
    CGContextRestoreGState(context)
}

Similarly you can follow the same approach for arcs, where you just need to replace the bezierPathWithOval method with bezierPathWithArcCenter method

Please note that:

CGFloat ovalPattern[] = {2, 1}; //2 is Dash width and 1 is gap between dashes

You can adjust these values for accuracy!

like image 122
Teja Nandamuri Avatar answered Nov 07 '22 19:11

Teja Nandamuri