見出し画像

SwiftUIで、オリジナルの棒グラフを作成する基本の方法

今回の内容
・オリジナルの棒グラフの基本的な作成方法。
・入門〜中級の読者様向けに、丁寧かつ簡潔に解説します。
・グラフ生成は、Githubライブラリを使用する方法もありますが、オリジナルで作成できれば、表現できるUXの幅が広がります。
・グラフ作成方法については、基本から応用まで、定期的に発表したいと思います。

テスト環境
Xcode 12.2
swift 5.3.1
iOS 14.2

1) データモデルの作成

1-1) モデル
まずはグラフデータのモデルを用意します。

struct DataModel: Identifiable {
   var id = UUID()
   var number: Int
   var month: String
}

・DataModelは、数値と月のシンプルなものにします。
・後ほど、ForEachに使用するので、Identifiableプロトコルに適合させています。
・idはUUID()で生成させ、データの一意性を担保します。

1-2) Viewとモックデータを準備
ViewとDataModelを使用したモックも準備しておきます。

struct BarChartView: View {

     let numbers = [DataModel(number: 100, month: "Jan"),
                    DataModel(number: 200, month: "Feb"),
                    DataModel(number: 300, month: "Mar"),
                    DataModel(number: 400, month: "Apr"),
                    DataModel(number: 500, month: "May"),
                    DataModel(number: 600, month: "Jun"),
                    DataModel(number: 700, month: "Jul"),
                    DataModel(number: 800, month: "Aug"),
                    DataModel(number: 900, month: "Sep"),
                    DataModel(number: 1100, month: "Oct"),
                    DataModel(number: 1300, month: "Nov"),
                    DataModel(number: 1500, month: "Dec")]
              
     var body: some View {
     
     }
 } 

・ViewはBarChartView、モックはnumbersという名前にしました。

2) Rectangleを横に並べて棒を生成

2-1)Hstack内にRectangleを生成

struct BarChartView: View {
   
  ~省略~
   
   var body: some View {
       HStack {
           Rectangle()
               .fill(Color.secondary)
               .frame(width: 20, height: 100)
       }
   }
}

・基本の棒グラフはRectangleとframeモディファイアを使って作っていきます。


2-2)ForEachでViewを繰り返し生成する
ForEachを使えば、繰り返し処理の中で、Viewを生成することができます。
ForEachを使用するためには、各要素を識別する一意のidが必要になります。
今回使用するDataModelは、あらかじめ id = UUID() で一意性を担保してます。

struct BarChartView: View {

    ~省略~
   
   var body: some View {
       HStack {
           ForEach(number) { item in
               VStack {
                   Rectangle()
                       .fill(Color.secondary)
                       .frame(width: 20, height: 100)
               }
           }
       }
   }
}

スクリーンショット 2021-01-13 21.15.36

・frameのheightが100で固定されているので、同じ形の棒が並んでいます。

3)棒をグラフにする

3-1)frameにグラフの数値を適用する
ForEachで一意に受け取ったitemを使用し、DetaModelの数値を扱い、frameにグラフの数値を適用します。

.frame(width: 20, height: CGFloat(item.number/10))

・CGFloat型でラップします。
・モックの値が大きいので「item.number / 10」で一桁小さくしています。 

3-2) Textラベルをつける
RectangleをVStack内にEmbedし、テキストラベルを付けます。

struct BarChartView: View {
   
  ~省略~
   
   var body: some View {
       HStack {
           ForEach(numbers) { item in
               VStack {
                   Rectangle()
                       .fill(Color.secondary)
                       .frame(width: 20, height: CGFloat(item.number))
                   Text("\(item.month)")
                       .font(.footnote)
                       .foregroundColor(.secondary)
               }
           }
       }
   }
}

スクリーンショット 2021-01-13 21.40.32


3-3) HStackのalignmentを使用する
HStackのイニシャライザにalignmentパラメータがあり、垂直方向の配置を指定できます。

HStack(alignment:.bottom) {
           ~省略~
       }       

スクリーンショット 2021-01-13 21.47.01

これで棒グラフができました。

4) その他

4-1) 上限値を設定する
上限値を設定する場合は、プロパティに下記を追加します。

let maxValue = 200

さらに、ForEachのクロージャ内でheight変数を作成し、min関数で上限値を設定します。

let height = min(item.number/10, maxValue)

・min関数は、引数(A, B)を比較し、小さい方を返す関数です。
数値(item.number/10)が上限値(maxValue)を超えた場合に、上限値(ここでは200)が返ってくる仕組みです。

最後に、frameにheightをセットして完了です。

struct BarChartView: View {
  ~省略~

   let maxValue = 200   

   var body: some View {
       ~省略~
           ForEach(number) { item in
               let height = min(item.number/10, maxValue)
               VStack {
                   Rectangle()
                       .fill(Color.secondary)
                       .frame(width: 20, height: CGFloat(height))
                 ~省略~
               }
           }
       }
   }
}


4-2) 目標値を設定し、それを超えた時に色を変える
プロパティに下記を追加します。

 let target = 1500

次に、fillモディファイアに条件式を挿入します。

.fill(item.number >= target ? Color.accentColor : Color.secondary)

・グラフ数値が目標値以上の場合は「Color.accentColor」を、そうでなければ「Color.secondary」を返すようにセットしています。

スクリーンショット 2021-01-13 22.14.37

これで、目標達成で色が変わる棒グラフができました。

簡単にですが、棒グラフ作成の基本方法は以上です。
グラフ・チャートはUI・UXにとても重要なので、これから定期的にアップしていきます。
円グラフの基本はこちらから。
最後まで見てくださってありがとうございました。

この記事が気に入ったらサポートをしてみませんか?