はじめに
本記事は前回の記事の実装を元に実装しています。
円グラフの要素を選択した時に動きを付けてみます。
サンプルアプリ
実装
onChange
内に書いてあるロジックはわかりにくいのでコメントを追加しています。
chartAngleSelection
に設定できるのはPlottable
に準拠しているもののみです。
import SwiftUI
import Charts
struct FavoriteFruit: Equatable {
let name: String
let count: Int
}
struct ContentView: View {
@State private var favoriteFruits: [FavoriteFruit] = [
.init(name: "りんご", count: 15),
.init(name: "いちご", count: 12),
.init(name: "さくらんぼ", count: 6),
.init(name: "ぶどう", count: 5),
.init(name: "バナナ", count: 4),
.init(name: "オレンジ", count: 2)
]
@State private var selectedCount: Int?
@State private var selectedFruit: FavoriteFruit?
var body: some View {
Chart(favoriteFruits, id: \.name) { favoriteFruit in
SectorMark(
angle: .value("count", favoriteFruit.count),
innerRadius: .inset(50),
outerRadius: selectedFruit == favoriteFruit ? .automatic : .inset(10),
angularInset: 3.0
)
.foregroundStyle(by: .value("name", favoriteFruit.name))
.opacity(selectedFruit == nil ? 1.0 : selectedFruit == favoriteFruit ? 1.0 : 0.5)
}
.chartAngleSelection(value: $selectedCount)
.onChange(of: selectedCount) {
// selectedCountがnilの時は、指がグラフに触れていない時
guard let selectedCount else {
// 指がグラフに触れていない時は、選択されたフルーツを解除する
self.selectedFruit = nil
return
}
// 累積カウント
var accumulatedCount = 0
// favoriteFruitsの先頭から順番に累積カウントを加算していく
let selectedFruit = favoriteFruits.first {
accumulatedCount += $0.count
// 累積カウントがselectedCountを超えた時点で、そのフルーツを選択されたフルーツとする
return selectedCount <= accumulatedCount
}
// 選択されたフルーツをselectedFruitに設定する
self.selectedFruit = selectedFruit
}
.frame(width: 300, height: 300)
}
}
おわり
めっちゃかっこいい動きですね!
参考記事
公式ドキュメント