quartzcore framework pi chart

//Swift Pie chart
//https://stackoverflow.com/a/34250475/13171606
//https://stackoverflow.com/questions/36708737/how-to-create-the-pie-chart-and-fill-percentage-in-swift

import Foundation
import UIKit

@IBDesignable class PieChart: UIView {
    var dataPoints: Dictionary<String,Double> = ["Alpha":1,"Beta":2,"Charlie":3,"Delta":4,"Echo":2.5,"Foxtrot":1.4] {
        didSet { setNeedsDisplay() }
    }
    @IBInspectable var lineWidth: CGFloat = 1.0 {
        didSet { setNeedsDisplay()
        }
    }
    @IBInspectable var lineColor: UIColor = uicolor_normal {
        didSet { setNeedsDisplay() }
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)!
        self.contentMode = .Redraw
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.clearColor()
        self.contentMode = .Redraw
    }

    override func drawRect(rect: CGRect) {


        // set font for labels
        let fieldColor: UIColor = UIColor.darkGrayColor()
        let fieldFont = uifont_piechartkey
        var fieldAttributes: NSDictionary = [
            NSForegroundColorAttributeName: fieldColor,
            NSFontAttributeName: fieldFont!
        ]

        // get the graphics context and prepare an inset box for the pie
        let ctx = UIGraphicsGetCurrentContext()
        let margin: CGFloat = lineWidth
        let box0 = CGRectInset(self.bounds, margin, margin)
        let keyHeight = CGFloat( ceil( Double(dataPoints.count) / 3.0) * 24 ) + 16
        let side : CGFloat = min(box0.width, box0.height-keyHeight)
        let box = CGRectMake((self.bounds.width-side)/2, (self.bounds.height-side-keyHeight)/2,side,side)
        let radius : CGFloat = min(box.width, box.height)/2.0


        // converts percentages to radians for drawing the segment
        func percent_to_rad(p: Double) -> CGFloat {
            let rad = CGFloat(p * 0.02 * M_PI)
            return rad
        }

        // draws a segment
        func draw_arc(start: CGFloat, end: CGFloat, color: CGColor) {
            CGContextBeginPath(ctx)
            CGContextMoveToPoint(ctx, box.midX, box.midY)
            CGContextSetFillColorWithColor(ctx, color)
            CGContextAddArc(ctx,box.midX,box.midY,radius-lineWidth/2,start,end,0)
            CGContextClosePath(ctx)
            CGContextFillPath(ctx)
        }
        // draws a key item
        func draw_key(keyName: String, keyValue: Double, color: CGColor, keyX: CGFloat, keyY: CGFloat) {
            CGContextBeginPath(ctx)
            CGContextMoveToPoint(ctx, keyX, keyY)
            CGContextSetFillColorWithColor(ctx, color)
            CGContextAddArc(ctx,keyX,keyY,8,0,CGFloat(2 * M_PI),0)
            CGContextClosePath(ctx)
            CGContextFillPath(ctx)
            keyName.drawInRect(CGRectMake(keyX + 12,keyY-8,self.bounds.width/3,16),withAttributes: fieldAttributes as? [String : AnyObject])
        }


        let total =  Double(dataPoints.values.reduce(0, combine: +)) // the total of all values
        // convert dictionary to sorted touples
        let dataPointsArray = dictionary_to_sorted_array(dataPoints)

        // now sort the dictionary into an Array
        var start = -CGFloat(M_PI_2) // start at 0 degrees, not 90
        var end: CGFloat
        var i = 0

        // draw all segments
        for dataPoint in dataPointsArray {
            end = percent_to_rad(Double( (dataPoint.value)/total) * 100 )+start
            draw_arc(start,end:end,color: uicolors_chart[i%uicolors_chart.count].CGColor)
            start = end
            i++
        }
        // the key
        var keyX = self.bounds.minX + 8
        var keyY = self.bounds.height - keyHeight + 32
            i = 0
        for dataPoint in dataPointsArray {
            draw_key(dataPoint.key, keyValue: dataPoint.value, color: uicolors_chart[i%uicolors_chart.count].CGColor, keyX: keyX, keyY: keyY)
            if((i+1)%3 == 0) {
                keyX = self.bounds.minX + 8
                keyY += 24
            } else {
                keyX += self.bounds.width / 3
            }
            i++
        }



    }
}

//This will create a pie chart, that looks something like this:

//[The finished chart[https://i.stack.imgur.com/K4hda.png]

//The other bits of code you'll need are the colours array:
		//"please follow the link for colors array" https://stackoverflow.com/a/34250475/13171606

//And the code to convert the dictionary to an array:

func dictionary_to_sorted_array(dict:Dictionary<String,Double>) ->Array<(key:String,value:Double)> {
    var tuples: Array<(key:String,value:Double)> = Array()
    let sortedKeys = (dict as NSDictionary).keysSortedByValueUsingSelector("compare:")
    for key in sortedKeys {
        tuples.append((key:key as! String,value:dict[key as! String]!))
    }
    return tuples
}

Are there any code examples left?
Made with love
This website uses cookies to make IQCode work for you. By using this site, you agree to our cookie policy

Welcome Back!

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign in
Recover lost password
Or log in with

Create a Free Account

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign up
Or sign up with
By signing up, you agree to the Terms and Conditions and Privacy Policy. You also agree to receive product-related marketing emails from IQCode, which you can unsubscribe from at any time.
Creating a new code example
Code snippet title
Source