ダーヤス.com プレミアム

ダーヤス.comにようこそ。プレミアムな情報で、ワークライフバランスの充実を図りませんか。

【Swift】健康とか栄養とかのバランスチャートのグラフを描く

      2016/06/07

グラフ1

グラフ2

グラフ3

【Swift】バナナ情報がどこでも手軽にメモできるアプリを作った。という記事を書いてから、単にメモできるだけじゃなくて、バランスチャートみたいなグラフを、入力したテキストフィールドからの値に応じて描けたらよりはかどるんじゃないかという意見が得られたので、そういうのを作ってみました。

とりあえずテキストフィールドを8つ用意してそれぞれ8つの軸を表示します。
0から5までの範囲で各軸の長さを設定して、0だったら原点、5だったら最大値のところに点をプロット。
その後、各プロット座標を結んで、面積が多いほどいい、という形です。

各軸を、価格とかキレとかコクとかのステータスを設定すれば、それっぽいバランスチャートができそうです。
よく栄養バランスとかで見られるような項目、たんぱく質とか脂質とかを設定すれば、栄養バランスが一目でわかる食品グラフが作れますね。

なお、8つにしたのは、一番グラフ描画が簡単そうだったからです。

最初5つにしようとしたら、正五角形の角度とか軸の長さとかの計算が面倒くさそう。

以下、コードです。
実は各点を結んでいるわけではなく、8つの三角形を作っているだけなのですが。。。
この部分、関数化できればもっとシンプルになったのですが、角度と軸長の関係をどう設定しようか考えなければならず、細切れの時間だと頭が働かないので、とりあえずそれっぽいグラフが書ければいいやと適当にやっただけです。
これだと応用が利かないので、いずれ角度と軸長の関係を関数化できるようにして、様々な多角形に対応できるようにしたいです。

View.Controller.swift

import UIKit

class ViewController: UIViewController {

    var textField1 = UITextField()
    var textField2 = UITextField()
    var textField3 = UITextField()
    var textField4 = UITextField()
    var textField5 = UITextField()
    var textField6 = UITextField()
    var textField7 = UITextField()
    var textField8 = UITextField()
    
    var button = UIButton()

    var graph = UIView()
    let lineX = UIBezierPath()
    let lineY = UIBezierPath()
    let line2 = UIBezierPath()
    let line3 = UIBezierPath()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        addTextField(textField1, i: 1)
        addTextField(textField2, i: 2)
        addTextField(textField3, i: 3)
        addTextField(textField4, i: 4)
        addTextField(textField5, i: 5)
        addTextField(textField6, i: 6)
        addTextField(textField7, i: 7)
        addTextField(textField8, i: 8)
        
        button.frame = CGRectMake(20, 200, 60, 30)
        button.setTitle("描画", forState: .Normal)
        button.setTitleColor(UIColor.blackColor(), forState: .Normal)
        button.layer.cornerRadius = 10
        button.backgroundColor = UIColor.yellowColor()
        button.addTarget(self, action: "picture", forControlEvents: .TouchUpInside)
        self.view.addSubview(button)
        
        
    }
    
    func addTextField (newTextField: UITextField, i: CGFloat) -> () {
        newTextField.frame = CGRectMake(20, 20*i, 200, 20)
        newTextField.borderStyle = UITextBorderStyle.RoundedRect
        self.view.addSubview(newTextField)
    }
    
    func picture() {
        //view作成
        let size = CGSize(width: 300, height: 300)
        graph.frame = CGRectMake(20, 230, size.width, size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        
        lineX.moveToPoint(CGPointMake(0, 150))//始点
        lineX.addLineToPoint(CGPointMake(300, 150))//終点
        lineY.moveToPoint(CGPointMake(150, 0))
        lineY.addLineToPoint(CGPoint(x: 150, y: 300))
        line2.moveToPoint(CGPointMake(150+150/sqrt(2), 150-150/sqrt(2)))
        line2.addLineToPoint(CGPointMake(150-150/sqrt(2), 150+150/sqrt(2)))
        line3.moveToPoint(CGPointMake(150-150/sqrt(2), 150-150/sqrt(2)))
        line3.addLineToPoint(CGPointMake(150+150/sqrt(2), 150+150/sqrt(2)))
        
        UIColor.blackColor().setStroke()
        lineX.stroke()
        lineY.stroke()
        line2.stroke()
        line3.stroke()

        let int1 = checkTextField(textField1)
        let int2 = checkTextField(textField2)
        let int3 = checkTextField(textField3)
        let int4 = checkTextField(textField4)
        let int5 = checkTextField(textField5)
        let int6 = checkTextField(textField6)
        let int7 = checkTextField(textField7)
        let int8 = checkTextField(textField8)
        
        //三角形1
        let triangle1 = UIBezierPath();
        triangle1.moveToPoint(CGPointMake(150, 150-30*CGFloat(int1)))
        triangle1.addLineToPoint(CGPointMake(150, 150))
        triangle1.addLineToPoint(CGPointMake(150+30*CGFloat(int2)/sqrt(2), 150-30*CGFloat(int2)/sqrt(2)))
        triangle1.addLineToPoint(CGPointMake(150, 150-30*CGFloat(int1)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle1.stroke()
        triangle1.fill()
        
        //三角形2
        let triangle2 = UIBezierPath();
        triangle2.moveToPoint(CGPointMake(150+30*CGFloat(int2)/sqrt(2), 150-30*CGFloat(int2)/sqrt(2)))
        triangle2.addLineToPoint(CGPointMake(150, 150))
        triangle2.addLineToPoint(CGPointMake(150+30*CGFloat(int3), 150))
        triangle2.addLineToPoint(CGPointMake(150+30*CGFloat(int2)/sqrt(2), 150-30*CGFloat(int2)/sqrt(2)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle2.stroke()
        triangle2.fill()
        
        //三角形3
        let triangle3 = UIBezierPath();
        triangle3.moveToPoint(CGPointMake(150+30*CGFloat(int3), 150))
        triangle3.addLineToPoint(CGPointMake(150, 150))
        triangle3.addLineToPoint(CGPointMake(150+30*CGFloat(int4)/sqrt(2), 150+30*CGFloat(int4)/sqrt(2)))
        triangle3.addLineToPoint(CGPointMake(150+30*CGFloat(int3), 150))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle3.stroke()
        triangle3.fill()
        
        //三角形4
        let triangle4 = UIBezierPath();
        triangle4.moveToPoint(CGPointMake(150+30*CGFloat(int4)/sqrt(2), 150+30*CGFloat(int4)/sqrt(2)))
        triangle4.addLineToPoint(CGPointMake(150, 150))
        triangle4.addLineToPoint(CGPointMake(150, 150+30*CGFloat(int5)))
        triangle4.addLineToPoint(CGPointMake(150+30*CGFloat(int4)/sqrt(2), 150+30*CGFloat(int4)/sqrt(2)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle4.stroke()
        triangle4.fill()
        
        //三角形5
        let triangle5 = UIBezierPath();
        triangle5.moveToPoint(CGPointMake(150, 150+30*CGFloat(int5)))
        triangle5.addLineToPoint(CGPointMake(150, 150))
        triangle5.addLineToPoint(CGPointMake(150-30*CGFloat(int6)/sqrt(2), 150+30*CGFloat(int6)/sqrt(2)))
        triangle5.addLineToPoint(CGPointMake(150, 150+30*CGFloat(int5)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle5.stroke()
        triangle5.fill()
        
        //三角形6
        let triangle6 = UIBezierPath();
        triangle6.moveToPoint(CGPointMake(150-30*CGFloat(int6)/sqrt(2), 150+30*CGFloat(int6)/sqrt(2)))
        triangle6.addLineToPoint(CGPointMake(150, 150))
        triangle6.addLineToPoint(CGPointMake(150-30*CGFloat(int7), 150))
        triangle6.addLineToPoint(CGPointMake(150-30*CGFloat(int6)/sqrt(2), 150+30*CGFloat(int6)/sqrt(2)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle6.stroke()
        triangle6.fill()
        
        //三角形7
        let triangle7 = UIBezierPath();
        triangle7.moveToPoint(CGPointMake(150-30*CGFloat(int7), 150))
        triangle7.addLineToPoint(CGPointMake(150, 150))
        triangle7.addLineToPoint(CGPointMake(150-30*CGFloat(int8)/sqrt(2), 150-30*CGFloat(int8)/sqrt(2)))
        triangle7.addLineToPoint(CGPointMake(150-30*CGFloat(int7), 150))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle7.stroke()
        triangle7.fill()
        
        //三角形8
        let triangle8 = UIBezierPath();
        triangle8.moveToPoint(CGPointMake(150-30*CGFloat(int8)/sqrt(2), 150-30*CGFloat(int8)/sqrt(2)))
        triangle8.addLineToPoint(CGPointMake(150, 150))
        triangle8.addLineToPoint(CGPointMake(150, 150-30*CGFloat(int1)))
        triangle8.addLineToPoint(CGPointMake(150-30*CGFloat(int8)/sqrt(2), 150-30*CGFloat(int8)/sqrt(2)))
        UIColor.redColor().setStroke()
        UIColor.redColor().setFill()
        triangle8.stroke()
        triangle8.fill()
        
        graph.layer.contents = UIGraphicsGetImageFromCurrentImageContext().CGImage
        UIGraphicsEndImageContext()
        
        self.view.addSubview(graph)
    }
    
    func checkTextField (newTextField: UITextField) -> (Int) {
        if newTextField.text == ""{
            newTextField.text = "0"
        }
        
        return Int(newTextField.text!)!
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

 - アプリ開発