WWDC22 で発表された Swift Charts (Beta) を早速使ってみる - 棒グラフ・線グラフ・点グラフ - 

先週のWWDC22で発表された新しいフレームワーク、[Swift Charts (Beta)](https://developer.apple.com/documentation/charts)を使ってみました！ :tada: 

チュートリアルを読み進めつつ、思ったことを書いていこうと思います。

## 環境

:::note warn
Swift Charts 含め、macOS や Xcode、iOS もまだ **Beta** になります。
:::

- macOS 13 beta 13.0
- Xcode 14.0 beta
- iOS 16.0 beta

## Swift Charts とは

**「データを有益にビジュアライズするための、強力で簡潔なSwiftUIフレームワーク」**
とのことです。

使用できるMarkの構造体はBetaの時点では、大きく6種類あるようです。
今回はそのうち、最初の3つのチュートリアルをやってみました。

|種類|図（Apple Developer Documentationより）|
|----------|---------------------------|
|BarMark（棒グラフ）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/4f53e5df-d11e-255f-9dd7-4ff93db840fa.png)|
|LineMark（線グラフ）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/6e550fb5-9f48-a29a-b0eb-a361f9f34377.png)|
|PointMark（点グラフ、散布図）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/8c4418bd-83a4-eb02-df08-c1c524e98b0d.png)|
|AreaMark（面グラフ）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/314aa89b-551e-9c4c-463d-d4f507d26cf2.png)|
|RectangleMark（四角形を使ってデータを表す。）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/6d721fa4-4e41-7313-cb27-f81858f26ae9.png)|
|RuleMark（直線を使ってデータを表す）|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/92a81ce2-99b4-2dec-d7fc-d227957e02ca.png)|

ローカライゼーションとアクセシビリティもサポートしているとのこと。

あと個人的には、「チャートにアニメーションを追加することもできる」というのがとても気になりますね :blush: 

## 実際にチャートを作ってみる

ここからは「[Creating a chart using Swift Charts](https://developer.apple.com/documentation/charts/creating-a-chart-using-swift-charts)」の内容と、

プラスアルファで 折れ線グラフと散布図もやってみます！

がんばる。

### 棒グラフを作る

ここはチュートリアル通りです。

まず前提ですが、
カラフルでそれぞれ形状の違うおもちゃがあります。これを Swift Charts を使用して、色や形状ごとのチャートを作っていこうというものになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/d59eccdb-63f0-21be-1879-149e99c20eee.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/daab4e52-b102-9833-2347-966c39b8c51a.png)

まずはチャートにするためのデータの作成です。
今回はチュートリアルなので、アプリ内で固定データを作成するようになっていますが、実際はネットワーク接続して取得してきたデータをダウンロードしたり、ファイルから読み込んできたデータを使うだろう、とのことです。

チュートリアルでは`type`は`Type`型ではなく`String`なのですが、好みでこうしてみただけです。

```swift:ToyShape
struct ToyShape: Identifiable {
    var type: `Type`
    var count: Double
    var id = UUID()

    enum `Type`: String {
        case cube = "四角形"
        case sphere = "球体"
        case pyramid = "ピラミッド"
    }
}
```

では早速、チュートリアル通り、棒グラフを作ってみます。

```swift:BarChartView
Chart {
  ForEach(data) { shape in
      BarMark(
        x: .value("形状", shape.type),
        y: .value("総数", shape.count)
      )
    }
}
```

わーい！ もうこれだけでなんだか嬉しいですねw

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/79fd024b-24cf-983e-b4ae-b2d2df92533c.png">

次は、おもちゃにはそれぞれ異なる色が付いているので、それを棒グラフで表現します。

先ほど作った構造体に`color`を追加。

```swift:ToyShape
struct ToyShape: Identifiable {
    var color: Color
    var type: `Type`
    var count: Double
    var id = UUID()

    // 省略

    // 追加
    enum Color: String {
        case green = "緑"
        case purple = "紫"
        case pink = "ピンク"
        case yellow = "黄色"
    }
}
```

肝心の`ContentView.swift`ですが、`foregroundStyle`モディファイアを追加するだけで、色のデータを反映することができるそうです。

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/4a6b81d4-dabf-3748-a209-2a6fcde565b0.png">

でもこれだと実際のおもちゃの色と、チャートの色が合っていません。`chartForegroundStyleScale`モディファイアを使ってこれを指定することができるそうです。

```swift:ContentView
Chart {
   ForEach(data) { shape in
       BarMark(
           x: .value("形状", shape.type.rawValue),
           y: .value("総数", shape.count)
       )
       .foregroundStyle(by: .value("形状", shape.color.rawValue))
   }
}
.chartForegroundStyleScale([
    ToyShape.Color.green.rawValue: .green,
    ToyShape.Color.purple.rawValue: .purple,
    ToyShape.Color.pink.rawValue: .pink,
    ToyShape.Color.yellow.rawValue: .yellow,
])
```

こんな感じになります。

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/eb484fc5-aff1-56ec-2419-3bf587fe57a8.png">

### 折れ線グラフを作る

ここで終わるとチュートリアルやっただけになるので、折れ線グラフも挑戦してみます。

チュートリアルではデータは、月間日照時間が使われていましたが、
私の好みで普段書いてるnote記事のビュー数の推移をグラフにしようと思います。

|期間|View数|
|-----------|--------------|
|1/13-2/12|960|
|2/13-3/12|1,162|
|3/13-4/12|2,096|
|4/13-5/12|1,875|

構造体を作ります。

```swift:NoteStatics
struct NoteStatics: Identifiable {
    var term: String
    var numOfViews: Int
    var id = UUID()
}
```

そしてチャートですが、折れ線グラフの場合は`LineMark`を使用します。

```swift:LineChartView
Chart(data) {
    LineMark(
        x: .value("期間（月）", $0.term),
        y: .value("ビュー数", $0.numOfLikes)
    )
}
```


これでこんなグラフが完成しました。
※途中からセグメントコントロールを実装したので、棒グラフの時と見た目が多少変わっています

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/242e7ca0-c201-eb21-b461-b0b40784a641.png">

### 点グラフ（散布図）

最後に、点グラフを作ってみます。
何か自分の身の回りのデータを持ってきたかったのですが、すぐ思いつかなかったので、ドキュメントのをそのまま拝借・・・

ドキュメントでは、昆虫の羽の数と羽の横幅を図にプロットしているようです。

まずデータの構造体から。

```swift:Insect
struct Insect: Identifiable {
    let name: String
    let family: String
    let wingLength: Double
    let wingWidth: Double
    let weight: Double
    let id = UUID()
}
```

次にViewです。

```swift:PointChartView
Chart(data) {
    PointMark(
        x: .value("羽の枚数", $0.wingLength),
        y: .value("羽の横幅", $0.wingWidth)
    )
}
```

ちょっとデータ量が少ないので寂しく見えますが、一応完成しました！

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/259e7a81-fc93-7f58-3b87-a641a4ea4801.png">

## おわりに

コード全体は以下に挙げています。

https://github.com/kamimi01/SwiftChartsBetaTest

WWDC22の中では興味のあるフレームワークだったので、とてもワクワクしました :heart: 
Beta版なので、正式版でどこまで変わってくるものなのかわかりませんが、そこまで変わらないものなんでしょうか？ :thinking: 

今回は6種類あるうちのよく使われるであろう、3つを作ってみました。残り3つもどこかでやってみたいです。

## 参考

https://developer.apple.com/documentation/Charts

https://developer.apple.com/documentation/charts/creating-a-chart-using-swift-charts

https://developer.apple.com/documentation/charts/barmark

https://developer.apple.com/documentation/charts/linemark

https://developer.apple.com/documentation/charts/pointmark