1
2

【SwiftUI】円グラフを選択した時に選択要素を強調したい

Posted at

はじめに

本記事は前回の記事の実装を元に実装しています。

円グラフの要素を選択した時に動きを付けてみます。

サンプルアプリ

Simulator Screen Recording - iPhone 15 - 2024-01-17 at 20.46.14.gif

実装

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)
    }
}

おわり

めっちゃかっこいい動きですね!

参考記事

公式ドキュメント

1
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
1
2