はじめに
はじめまして! 2022年5月キャリア入社、HealthCare Innovation Group(HIG)1の橋本です。技術ブログ初投稿です。
iOS16からApple標準で利用できるようになったSwift Chartsというグラフ等を作成できるフレームワークを取り上げます。
取り上げた理由としては、2点あります。
- 現在のプロジェクトで活用する機会がありそうなため、事前にキャッチアップしておきたいと考えたため
- データ分析の分野にも興味があり、後ほど投稿しよう思っているSwiftで機械学習をしたときの結果をきれいに可視化してみたいと思っているから
早速本題に入っていきます。内容は次のような構成です。
内容
- Swift Chartsとは
- Swift Chartsの基本的な使い方
- グラフを描く要素を定義するデータ構造を設計する
- 6つのMarkとその使い方
- AreaMask
- LineMark
- PointMark
- RectangleMark
- RuleMark
- BarMark
- iPhoneのScreen Timeの表示をSwift Chartsで作ってみる
Swift Chartsとは
Swift Chartsとは、WWDC2022で発表されたカスタマイズされたグラフを作成できるSwiftUIフレームワークです。
https://developer.apple.com/documentation/charts
イメージとしては、以下のように様々なグラフを描くことができます。
また、WWDC2023のセッション(Explore pie charts and interactivity in Swift Charts)で7つ目となるSectorMark
が発表されました。SectorMark
を使うことで簡単にPie Chartを作ることがiOS17から可能になるとのことです。
https://developer.apple.com/videos/play/wwdc2023/10037/
https://developer.apple.com/documentation/charts/sectormark
Swift Chartsの基本的な使い方
簡単な棒グラフを作っていきます。
完成イメージは、縦軸が値段、横軸にフルーツが並ぶ棒グラフです。
使用する要素は以下のとおりです。
フルーツ | 値段 |
---|---|
りんご | 100円 |
オレンジ | 50円 |
バナナ | 200円 |
早速作っていきます。
まず、Swift Chartsを利用するために、Charts
をインポートします。
import Charts |
これによって、Swift Chartsが使えるようになりました。
次にグラフを描画する場所を定義します。
グラフを記述する場所として、View配下にChart {}
を次のように記載します。
struct ContentView: View { |
次に、今回は棒グラフを作成するので、棒グラフを描くことができるBarMark
を使っていきます。
さきほどのコードにBarMark
を追加します。
Chart { |
BarMark内のx: .value("Fruit", "Apple")
でx軸のラベル自体をFruit
と定義し、表示されている1つのバー要素がApple
であることを示しています。y: .value("Price", 100)
も同様に、y軸のラベル自体をPrice
と定義し、表示されている1つのバー要素が100
であることを示しています。
”りんご” のバーを追加できましたので、オレンジ、バナナを追加します。
追加する方法は、とても簡単でオレンジ用、バナナ用のBarMarkをそれぞれ追加するだけです。
Chart { |
これで完成イメージ通りのグラフが完成しました。しかし、この方法ですとBarMarkを要素が1つ追加するごとに増えていくので、数が多くなると大変見づらくなってしまいます。
そこで、グラフの要素を構造体で定義することでView
内を簡潔に記載できます。
グラフを描く要素を定義するデータ構造を設計する
グラフで利用するデータ構造の一般的な設計について説明します。
Chartsでは、ForEachのようにループ文を使うことができるため、構造体をIdentifiable
プロトコルに準拠させ、一意のid
をプロパティとして定義しておきます。
struct Data: Identifiable { |
これを用いて、先程紹介した棒グラフを実装すると次のようになります。
// 棒グラフの各要素を定義する |
Charts
をForEach
のように利用できるため、これまでSwiftUIを触ったことがある人にはとても使いやすいと思いました。
6つのMarkとその使い方
6つのグラフを描画するMarkの使い方について、紹介します。
表に6つのMark名と主に使われるグラフとそのイメージ画像を一覧化しています。
名前 | 説明 | イメージ |
---|---|---|
AreaMark | 面グラフ | |
LineMark | 折れ線グラフ | |
PointMark | 散布図 | |
RectangleMark | ヒートマップ | |
RuleMark | 水平線、垂直線 | |
BarMark | 棒グラフ |
BarMarkの使い方は、すでに紹介しましたので、残りの5つのMarkのサンプルコードを次に記載します。
(ここでは基本的にデータ構造などのコードは省き、Chart{}
内のコードのみを載せています)。
Area Markのサンプルコード
Chart(cheeseburgerCost) { |
LineMarkのサンプルコード
Chart(data) { |
PointMarkのサンプルコード
Chart(data) { |
RectangleMarkのサンプルコード
このサンプルコードでは、width
とheight
でバーエリア内の比率を1.0にすることでヒートマップを作成しています。作成されるヒートマップは、上記で記載している表中のイメージのものです。
struct MatrixEntry: Identifiable { |
RuleMarkのサンプルコード
private var data: [Pollen] = [ |
SectorMarkのサンプルコード(iOS17以降)
WWDC2023で発表されたSectorMark
のサンプルコードです。BarMark
等で使っていたx:
をangle
に変えるだけで、簡単にPie chartsに変換できます。
また、innnerRadius:
、angularInset
でPie chartsをカスタマイズできます。innnerRadius:
を使用することで、パイチャートの内部を指定の比率だけくり抜き、ドーナッツチャートにすることもできます。
var body: some View { |
再掲となりますが、以下のWWDC2023のセッション動画を見ていただけると、SectorMark
について理解が進むと思います。
https://developer.apple.com/videos/play/wwdc2023/10037/
スクリーンタイムのグラフを模倣して作ってみた
最後に、学習してきた知識を活用して、iPhoneアプリなどに標準で搭載されているスクリーンタイムのグラフを模倣してみました。
環境
- macOS: Ventura 13.4.1
- Xcode: Version 14.3.1 (14E300c)
struct BarItem: Identifiable { |
本物にかなり似たグラフを実装できたと思います。
より本物のスクリーンタイムに合わせるには、以下をうまく実装に反映させる必要があります。
RuleMark
の点線の横に、平均という文字を入れること- 縦軸の目盛りを調節すること
- 縦軸の目盛りに単位を追加すること
- 日、月、などの曜日をそれぞれの要素内で左に寄せること
これらの課題は、時間を見つけて改善していきたいと思います。
さいごに
今回は、iOS16から利用できるようになったSwift Chartsについて理解を深めました。
今後もSwift周りで学習した内容を投稿していきたいと思いますので、その際もお読みいただけると嬉しいです。
参考リンク
https://developer.apple.com/documentation/charts/areamark
https://developer.apple.com/documentation/charts/linemark
https://developer.apple.com/documentation/charts/pointmark
https://developer.apple.com/documentation/charts/rectanglemark