はじめに
SwiftUIのChartを極めようの会を1人でしてます。
解決したい課題
棒グラフにグラデーションを設定します。
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: 17, min: 13),
.init(day: 2, max: 25, min: 10),
.init(day: 3, max: 12, min: 11),
.init(day: 4, max: 21, min: 11),
.init(day: 5, max: 10, min: 6)
]
var body: some View {
Chart {
ForEach(temperatures, id: \.day) { temperature in
BarMark(
x: .value("day", temperature.day),
y: .value("max", temperature.max),
width: 30
)
.foregroundStyle(by: .value("max", "最高気温"))
}
}
.chartForegroundStyleScale(["最高気温": LinearGradient(colors: [.purple, .red, .orange, .yellow], startPoint: .top, endPoint: .bottom)])
.frame(width: 300, height: 300)
}
}
上記のコードで実行すると以下のようなUIになります。
まぁ悪くないですが、グラデーションの終点が揃っていなので色から高い低いが分かりにくいです。
以下のようにグラデーションの始点と終点を揃えることによって、色からも高い低いが理解しやすいです。
ではSwiftUIのChartでどのように実装するのでしょうか?
実装
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: 17, min: 13),
.init(day: 2, max: 25, min: 10),
.init(day: 3, max: 12, min: 11),
.init(day: 4, max: 21, min: 11),
.init(day: 5, max: 10, min: 6)
]
var body: some View {
Chart {
ForEach(temperatures, id: \.day) { temperature in
BarMark(
x: .value("day", temperature.day),
y: .value("max", temperature.max),
width: 30
)
.foregroundStyle(by: .value("max", "最高気温"))
+ .alignsMarkStylesWithPlotArea()
}
}
.chartForegroundStyleScale(["最高気温": LinearGradient(colors: [.purple, .red, .orange, .yellow], startPoint: .top, endPoint: .bottom)])
.frame(width: 300, height: 300)
}
}
おわり
alignsMarkStylesWithPlotArea
を付与することによってグラデーションの終点が揃えられました。
公式ドキュメント