Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

リアルタイムグラフを線描画するコードを書きました(iOS9)

f:id:weed_7777:20160707174033g:plain

グラフデータの入った配列からベジエパスでグラフにするのですが、その前に過去のグラフを上から塗りつぶすのがポイントです。

以下がコードです。UIViewのサブクラスを作り、drawRect()をoverrideします。

2016年7月20日、修正しました。

    override func drawRect(rect: CGRect) {

        // 描画済みのグラフを削除グラフリストに追加する
        graphsToDelete += [self.graph]
        
        // 描画済みのグラフを消す
        for graph in graphsToDelete {
            graph.lineWidth = 2
            graph.strokeWithBlendMode(CGBlendMode.Normal, alpha: 1.0)
            graph.stroke()
        }
        
        func point(n: Int, value: Float) -> CGPoint {
            return CGPointMake(
                5 * CGFloat(n),
                CGFloat(height - yMargin) - 5 * CGFloat(value))
        }
        
        func drawGraph(values:[Float!], maxCountToDraw: Int!) {
            var valuesToDraw = values
            var c = values.count
            
            // データが多いときは古い部分を消す
            if maxCountToDraw < c {
                valuesToDraw[0...c-(maxCountToDraw+1)] = []
                c = maxCountToDraw
            }
            
            // 最終点からさかのぼってグラフを描画する
            graph.moveToPoint(point(maxCountToDraw, value: valuesToDraw[c-1]))
            for i in 1 ..< c {
                graph.addLineToPoint(point(maxCountToDraw-i, value: valuesToDraw[c-i-1]))
            }
            
            // ベジエパスを描画する
            graph = UIBezierPath()
            UIColor.redColor().setStroke()
            graph.lineWidth = 2
            graph.stroke()
        }

        drawGraph(values, maxCountToDraw: xMax)

更新するときは以下のような感じです:

            self.graphView.setNeedsDisplay()

それにしてもSwiftになって配列がらみのコードは、とても読みやすくなりましたね。