4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】折れ線グラフを2つ表示する

Last updated at Posted at 2024-01-11

はじめに

SwiftUIのChartsで折れ線グラフを2つ表示させようとした時に苦戦したので記録しておきます。

サンプルアプリ

simulator_screenshot_DB3BA4F1-34EA-42AD-AAA1-773BD7E486DC.png

ダメな例

以下のようにLineMarkforegroundStyleをつけることで色を変えることができます。

Chart {
    ForEach(temperatures, id: \.day) { temperature in
        LineMark(
            x: .value("day", temperature.day),
            y: .value("max", temperature.max)
        )
        .foregroundStyle(Color.orange)
    }
}
.frame(width: 300, height: 500)

スクリーンショット 2024-01-11 22.30.03.png

しかし、2つグラフを表示しようとしても、1つしか表示されません。

Chart {
    ForEach(temperatures, id: \.day) { temperature in
        LineMark(
            x: .value("day", temperature.day),
            y: .value("max", temperature.max)
        )
        .foregroundStyle(Color.orange)
        
        LineMark(
            x: .value("day", temperature.day),
            y: .value("min", temperature.min)
        )
        .foregroundStyle(Color.cyan)
    }
}
.frame(width: 300, height: 500)

スクリーンショット 2024-01-11 22.31.35.png

正しい実装

import SwiftUI
import Charts

struct Temperature {
    let day: Int
    let max: Double
    let min: Double
}

struct ContentView: View {
    @State private var temperatures: [Temperature] = [
        .init(day: 1, max: 23, min: 13),
        .init(day: 2, max: 25, min: 10),
        .init(day: 3, max: 23, min: 11),
        .init(day: 4, max: 21, min: 11),
        .init(day: 5, max: 18, min: 12),
        .init(day: 6, max: 19, min: 13),
        .init(day: 7, max: 18, min: 15),
        .init(day: 8, max: 22, min: 9),
        .init(day: 9, max: 23, min: 10),
        .init(day: 10, max: 24, min: 13),
    ]
    
    var body: some View {
        Chart {
            ForEach(temperatures, id: \.day) { temperature in
                LineMark(
                    x: .value("day", temperature.day),
                    y: .value("max", temperature.max)
                )
+               .foregroundStyle(by: .value("max", "最高気温"))
                
                LineMark(
                    x: .value("day", temperature.day),
                    y: .value("min", temperature.min)
                )
+               .foregroundStyle(by: .value("min", "最低気温"))
            }
        }
+       .chartForegroundStyleScale(["最高気温": Color.orange, "最低気温": Color.cyan])
        .frame(width: 300, height: 500)
    }
}

解説

割とわかりにくいので解説します。
foregroundStyle(by:)を使用して、キーを指定します。

.foregroundStyle(by: .value("max", "ここの値がキー1"))
.foregroundStyle(by: .value("min", "ここの値がキー2"))

foregroundStyle(by:)で指定したキーをchartForegroundStyleScaleで色とセットで渡します。

.chartForegroundStyleScale(["ここの値がキー1": Color.orange, "ここの値がキー2": Color.cyan])

このようにキーと色を紐付けることで2つのグラフが表示されるようになります。

chartForegroundStyleScaleに存在しないキーを渡すとクラッシュします。

おわり

チャート用の機能がいっぱいあるのでちゃんとインプットしていかないと使いこなせなさそうです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?