iPhone半円チャート

半円状のチャートを表示するiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SpriteKit

class ViewController: UIViewController {

    weak var scene : SKScene?

    var levels = [75, 60, 80, 33, 90, 48] // max 100

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createHalfCircle()

    }

    

    func setupScene() {

        let sv = SKView(frame: view.bounds)

        let s = SKScene(size: sv.frame.size)

        s.backgroundColor = UIColor(hue: 0.5, saturation: 0.3, brightness: 1, alpha: 1)

        sv.presentScene(s)

        view.addSubview(sv)

        

        scene = s

    }

    func createHalfCircle() {

        let r = CGRectGetMaxX(view.bounds) * 0.45

        let path = UIBezierPath(arcCenter: CGPointZero, radius: r, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true)

        path.closePath()

        let half = SKShapeNode(path: path.CGPath)

        half.name = “half circle”

        half.position = CGPoint(x: CGRectGetMidX(view.bounds), y: 10)

        half.fillColor = UIColor(hue: 0.1, saturation: 0.05, brightness: 1, alpha: 1)

        half.strokeColor = UIColor(white: 0.1, alpha: 0.2)

        half.lineWidth = 5

        scene?.addChild(half)

        

        let start = 5.0 * CGFloat(M_PI)/12.0

        let fan = UIBezierPath(arcCenter: CGPointZero, radius: r, startAngle: start, endAngle: start + CGFloat(M_PI) / 6.0, clockwise: true)

        fan.addLineToPoint(CGPointZero)

        fan.closePath()

        

        // level

        levels.foreach({ (level, idx) -> Void in

            let arc = SKShapeNode(path: fan.CGPath)

            arc.name = “arc\(idx)

            arc.fillColor = UIColor(hue: CGFloat(idx) * 0.1, saturation: 0.2, brightness: 0.8, alpha: 1)

            half.addChild(arc)

            arc.zRotation = CGFloat(idx) * CGFloat(M_PI) / 6.0 CGFloat(M_PI) * (5.0/12.0)

            arc.xScale = CGFloat(level) / 100.0

            arc.yScale = CGFloat(level) / 100.0

        })

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let halfCircleChart = scene?.childNodeWithName(“half circle”)

        

        // refresh ramdom data

        levels = levels.map {(T) -> Int in return Int(arc4random_uniform(100)) }

        levels.foreach { (e, i) -> Void in

            let arc = halfCircleChart?.childNodeWithName(“arc\(i)) as SKShapeNode

            arc.runAction(SKAction.scaleTo(CGFloat(e) / 100.0, duration: 0.5))

        }

    }

}

extension Array {

    func foreach (doit:(Element, Int) -> Void) {

        for (i, e) in enumerate(self) { doit(e, i) }

    }

}