import SwiftUI

    / 今日分析 / struct TodayPreviewView: View { var body: some View { VStack{ ZStack{ HStack{ Button {

    1. } label: {
    2. Image(systemName: "line.horizontal.3")
    3. .resizable()
    4. .frame(width: 20, height: 15)
    5. .foregroundColor(.black)
    6. }
    7. Spacer()
    8. Button {
    9. } label: {
    10. Image(systemName: "bell.fill")
    11. .foregroundColor(.black)
    12. }
    13. }
    14. Text("My Usage")
    15. .fontWeight(.bold)
    16. }
    17. .padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
    18. .padding()
    19. .overlay {
    20. Rectangle().stroke(Color.black.opacity(0.05), lineWidth: 2)
    21. }
    22. // create pie chart
    23. GeometryReader { g in
    24. ZStack{
    25. ForEach(0..<pieData.count){i in
    26. DrawShape(center: CGPoint(x: g.frame(in: .global).width / 2, y: g.frame(in: .global).height / 2), index: i)

    // Path{path in // path.move(to: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2)) // path.addArc(center: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2), radius: 180, startAngle: .zero, endAngle: .init(degrees: 90), clockwise: false) // } // .fill(Color.yellow) } } } .frame(height: 360) .padding(.top, 20) .clipShape(Circle()) .shadow(radius: 8)

    1. // since it is in circle shape so were going to clip it in circle...
    2. // since radius is 180 so circle size will be 360
    3. VStack{
    4. ForEach(pieData){i in
    5. HStack{
    6. Text(i.name)
    7. .frame(width: 100)
    8. // fixed width...
    9. GeometryReader { g in
    10. HStack{
    11. Spacer(minLength: 0)
    12. Rectangle()
    13. .fill(i.color)
    14. .frame(width: getWidth(width: g.frame(in: .global).width, value: i.percent), height: 10)
    15. Text(String(format: "\(i.percent)", "%.0f"))
    16. .fontWeight(.bold)
    17. .padding(.leading, 10)
    18. }
    19. }
    20. }
    21. .padding(.top, 18)
    22. }
    23. }
    24. .padding()
    25. Spacer()
    26. }
    27. .edgesIgnoringSafeArea(.top)
    28. }
    29. func getWidth(width: CGFloat, value : CGFloat) -> CGFloat{
    30. let temp = value / 100
    31. return temp * width
    32. }

    }

    struct DrawShape: View{ var center: CGPoint var index : Int

    1. var body: some View{
    2. Path{path in
    3. path.move(to: self.center)
    4. path.addArc(center: self.center, radius: 180, startAngle: .init(degrees: from()), endAngle: .init(degrees: to()), clockwise: false)
    5. }
    6. .fill(pieData[index].color)
    7. }
    8. func from() -> Double{
    9. if index <= 0{
    10. return 0
    11. }
    12. var temp : Double = 0
    13. for i in 0...index-1{
    14. temp += Double(pieData[i].percent / 100) * 360
    15. }
    16. return temp
    17. }
    18. func to() -> Double{
    19. var temp : Double = 0
    20. // because we need current degree
    21. for i in 0...index{
    22. temp += Double(pieData[i].percent / 100) * 360
    23. }
    24. return temp
    25. }

    }

    struct TodayPreviewView_Previews: PreviewProvider { static var previews: some View { TodayPreviewView() } }

    // sample data struct Pie : Identifiable{ var id : Int var percent: CGFloat var name: String var color: Color }

    var pieData = [ Pie(id: 0, percent: 10, name: “测试”, color: Color.green), Pie(id: 1, percent: 20, name: “墨鱼🦑”, color: Color.red), Pie(id: 2, percent: 15, name: “工作”, color: Color.purple), Pie(id: 3, percent: 50, name: “学习”, color: Color.gray), Pie(id: 4, percent: 5, name: “睡眠”, color: Color.yellow), ] ```